为外键字段创建 post_save 信号

我有一个包含经验和教育作为外键领域的配置文件模型。当我访问配置文件模板时,它会抛出。

http://img.mukewang.com/6181288e0001f6da07350346.jpg

我试过post_save,


def create_education(sender, instance, created, **kwargs):

    if created:

        Profile.objects.create(education=instance)


    post_save.connect(create_education, sender=CustomUser)

它抛出这个错误,

http://img2.mukewang.com/6181289b00012dd609210173.jpg

如何定义 post_save 信号以便在创建个人资料时创建经验和教育?


注意:我仔细检查了错误是因为外部字段为空,即当我在 django admin 中添加经验和教育字段时没有错误。


模型.py


class Work_Experience(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 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 Profile(models.Model):    

    experience    = models.ForeignKey(Work_Experience, on_delete=models.SET_NULL, null=True, blank=True)

    education     = models.ForeignKey(Education, on_delete=models.SET_NULL, null=True, blank=True)



慕姐4208626
浏览 253回答 2
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。

阿晨1998

你不能那样做,我建议你阅读 django 文档。只需这样做: 在此处更新下面的代码按预期工作..from django.conf import settingsfrom django.db.models.signals import post_savefrom django.dispatch import receiverfrom django.contrib.auth.base_user import AbstractBaseUserfrom latiro_app.managers import UserManagerclass 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)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python