gpt4 book ai didi

python - 为外键字段创建 post_save 信号

转载 作者:行者123 更新时间:2023-12-01 01:13:30 26 4
gpt4 key购买 nike

我有一个个人资料模型,其中包含作为外国关键领域的经验和教育。当我访问个人资料模板时,它会抛出异常。

enter image description here

我尝试过 post_save,

def create_education(sender, instance, created, **kwargs):
if created:
Profile.objects.create(education=instance)

post_save.connect(create_education, sender=CustomUser)

它抛出这个错误,

enter image description here

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

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

models.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)

forms.py

class ProfileSettingsForm(forms.ModelForm):
job_title = forms.CharField(max_length=40, required=False)
company = forms.CharField(max_length=40, required=False)
description = forms.CharField(max_length=40, required=False)
exp_start_date = forms.DateField(required=False)
exp_end_date = forms.DateField(required=False)

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)

def __init__(self, *args, **kwargs):
instance = kwargs.get('instance', None)

super(ProfileSettingsForm, self).__init__(*args, **kwargs)
self.fields['job_title'].initial = self.instance.experience.job_title
self.fields['company'].initial = self.instance.experience.company
self.fields['description'].initial = self.instance.experience.description
self.fields['exp_start_date'].initial = self.instance.experience.exp_start_date
self.fields['exp_end_date'].initial = self.instance.experience.exp_end_date

self.fields['degree'].initial = self.instance.education.degree
self.fields['school'].initial = self.instance.education.school
self.fields['edu_start_date'].initial = self.instance.education.edu_start_date
self.fields['edu_end_date'].initial = self.instance.education.edu_end_date

def save(self, commit=True):
model = super(ProfileSettingsForm, self).save(commit=False)
jt = self.cleaned_data['job_title']
co = self.cleaned_data['company']
desc = self.cleaned_data['description']
esd = self.cleaned_data['exp_start_date']
eed = self.cleaned_data['exp_end_date']

degree = self.cleaned_data['degree']
school = self.cleaned_data['school']
edusd = self.cleaned_data['edu_start_date']
edued = self.cleaned_data['edu_end_date']


if model.experience:
model.experience.job_title = jt
model.experience.company = co
model.experience.description = desc
model.experience.exp_start_date = esd
model.experience.exp_end_date = eed
model.experience.save()
else:
model.experience = Work_Experience.objects.create(job_title=jt,
company=co,
description=desc,
exp_start_date=esd,
exp_end_date=eed)

if model.education:
model.education.degree = degree
model.education.school = school
model.education.edu_start_date = edusd
model.education.edu_end_date = edued
model.education.save()
else:
model.education = Education.objects.create(degree=degree,
school=school,
edu_start_date=edusd,
edu_end_date=edued)
if commit:
model.save()

return model

Views.py

class ProfileSettingsView(UpdateView):
model = Profile
form_class = ProfileSettingsForm
pk_url_kwarg = 'pk'
context_object_name = 'object'
template_name = 'profile_settings.html'

def get_success_url(self):
return reverse_lazy('users:profile_settings', args = (self.object.id,))

更新

如果我删除表单中的 init() 方法,错误就会解决。但是保存后,我不会从表单字段中的数据库中获取值。如何重写 init() 方法?

def __init__(self, *args, **kwargs):
instance = kwargs.get('instance', None)

super(ProfileSettingsForm, self).__init__(*args, **kwargs)
self.fields['job_title'].initial = self.instance.experience.job_title
self.fields['company'].initial = self.instance.experience.company
self.fields['description'].initial = self.instance.experience.description
self.fields['exp_start_date'].initial = self.instance.experience.exp_start_date
self.fields['exp_end_date'].initial = self.instance.experience.exp_end_date

self.fields['degree'].initial = self.instance.education.degree
self.fields['school'].initial = self.instance.education.school
self.fields['edu_start_date'].initial = self.instance.education.edu_start_date
self.fields['edu_end_date'].initial = self.instance.education.edu_end_date

最佳答案

为什么会出错?

行中:

self.fields['job_title'].initial = self.instance.experience.job_title

您正在处理一个没有相关经验Profile实例。

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

如果您希望每次创建个人资料时都会填充经验教育,您应该有一个类似以下的信号:

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)

为什么调用表单的save()时没有触发post_save信号?

model = super(ProfileSettingsForm, self).save(commit=False)

根据文档:

This save() method accepts an optional commit keyword argument, which accepts either True or False. If you call save() with commit=False, then it will return an object that hasn’t yet been saved to the database. In this case, it’s up to you to call save() on the resulting model instance. This is useful if you want to do custom processing on the object before saving it, or if you want to use one of the specialized model saving options. commit is True by default.

所以当你这样做时:

model.experience.job_title = jt

您的 post_save 信号尚未触发,因此 model.experience 仍为 None,因此出现错误:

'NoneType' object has no attribute job_title.

关于python - 为外键字段创建 post_save 信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54599050/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com