2 回答
TA贡献1863条经验 获得超2个赞
为什么会出错?
在行中:
self.fields['job_title'].initial = self.instance.experience.job_title
您正在处理一个Profile没有相关experience.
如何定义 post_save 信号以便在创建个人资料时创建经验和教育?
如果你想每次创建一个Profile它都会填充 amexperience并且education你应该有一个像这样的信号:
def create_profile(sender, instance, created, **kwargs):
if created:
experience = Work_Experience.objects.create(profile=instance)
education = Education.objects.create(profile=instance)
post_save.connect(create_profile, sender=Profile)
为什么post_save调用save()表单的时候没有触发信号?
model = super(ProfileSettingsForm, self).save(commit=False)
根据文档:
这个 save() 方法接受一个可选的 commit 关键字参数,它接受 True 或 False。如果您使用 commit=False 调用 save(),那么它将返回一个尚未保存到数据库的对象。在这种情况下,您可以在生成的模型实例上调用 save() 。如果您想在保存对象之前对其进行自定义处理,或者您想使用专门的模型保存选项之一,这将非常有用。默认情况下,commit 为 True。
所以当你做的时候:
model.experience.job_title = jt
您的post_save信号尚未触发,因此model.experience仍然存在None错误:
'NoneType' 对象没有属性 job_title。
TA贡献2037条经验 获得超6个赞
你不能那样做,我建议你阅读 django 文档。只需这样做: 在此处更新
下面的代码按预期工作..
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.base_user import AbstractBaseUser
from latiro_app.managers import UserManager
class User(AbstractBaseUser):
email = models.CharField(verbose_name='email or phone number ', max_length=50, unique=True )
first_name = models.CharField('first name', max_length=15,blank=True)
last_name = models.CharField('last name', max_length=15,blank=True)
country = CountryField(blank=True)
date_joined = models.DateTimeField('date joined', auto_now_add=True)
slug = models.SlugField('slug', max_length=50, unique=True, null=True)
is_active = models.BooleanField('active',default=False)
is_staff = models.BooleanField('staff', default=False)
email_confirmed = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
class Meta:
db_table = "users"
permissions = (
("edit_user", "Edit User"),
)
class WorkExperience(models.Model):
job_title = models.CharField(max_length=100, null=True, blank=True)
company = models.CharField(max_length=100, null=True, blank=True)
description = models.CharField(max_length=300, null=True, blank=True)
exp_start_date = models.DateField(null=True, blank=True)
exp_end_date = models.DateField(null=True, blank=True)
class Meta:
db_table = "experience"
def __str__(self):
return (self.job_title)
class Education(models.Model):
degree = models.CharField(max_length=100, null=True, blank=True)
school = models.CharField(max_length=100, null=True, blank=True)
edu_start_date = models.DateField(null=True, blank=True)
edu_end_date = models.DateField(null=True, blank=True)
class Meta:
db_table = "education"
def __str__(self):
return (self.degree)
class Profile (models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete= models.CASCADE,
verbose_name='list of users', null=True)
experience = models.ForeignKey(WorkExperience, on_delete=models.SET_NULL, null=True, blank=True)
education = models.ForeignKey(Education, on_delete=models.SET_NULL, null=True, blank=True)
def __str__(self):
return (self.user)
class Meta:
db_table = "profile"
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_profile(sender, instance, created, **kwargs):
if created and not kwargs.get('raw', False):
profile = Profile(user=instance)
profile.save()
这应该有效。在我的数据库上测试:
+----+--------------+---------------+---------+
| id | education_id | experience_id | user_id |
+----+--------------+---------------+---------+
| 1 | NULL | NULL | 2 |
+----+--------------+---------------+---------+
更新配置文件时,user_id 实例将更新education_id 和experience_id 上的空值。
现在用户可以像这样更新他/她的个人资料: 注意:我没有使用信号。
#Form.py
class EducationForm(forms.ModelForm):
degree = forms.CharField(max_length=40, required=False)
school = forms.CharField(max_length=40, required=False)
edu_start_date = forms.DateField(required=False,
input_formats=settings.DATE_INPUT_FORMATS)
edu_end_date = forms.DateField(required=False,
input_formats=settings.DATE_INPUT_FORMATS)
class Meta:
model= Education
fields =["degree","school", "edu_start_date","edu_start_date"]
#View.py
class EducationFormView(UpdateView):
model = Education
form_class = EducationForm
template_name = 'latiro_app/education_form.html'
def get_success_url(self):
return reverse_lazy('users:profile_settings',
args =(self.object.id,))
def get(self, form, ** kwargs):
profile_instance = get_object_or_404(self.model, user_id=self.kwargs['pk'])
#Pass user profile data to the form
context = {'form':self.form_class(instance=profile_instance)}
if self.request.is_ajax():
kwargs['ajax_form'] = render_to_string(self.template_name, context, request=self.request )
return JsonResponse(kwargs)
else:
return render(self.request, self.template_name, context)
添加回答
举报