我有一个Django ModelForm,我想在验证时用一个用户实例设置一个ForeignKey,它隐藏在模板上,所以用户无法设置它。
观点:
def view1(request):
if request.method == "POST":
model1form = Model1Form(request.POST, request.FILES, user=request.user)
if model1form.is_valid(): # fails here
print "is valid"
形式:
class Model1Form(forms.ModelForm):
class Meta:
model = Model1
fields = ['person_id', 'start_date', 'end_date']
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(Model1Form, self).__init__(*args, **kwargs)
def clean(self):
cleaned_data = super(Model1Form, self).clean()
start_date = cleaned_data.get("start_date")
end_date = cleaned_data.get("end_date")
username = self.user
person = Person.objects.get(username_field=username)
person_id = person.id
print person_id # this prints fine
# custom validation
return cleaned_data
当我运行is_valid()时,这个clean方法失败了。但是在没有person_id的情况下运行正常。我究竟做错了什么?
型号:
class Model1(models.Model):
person_id = models.ForeignKey(Person, null=True)
start_date = models.DateField(null=True, blank=True)
end_date = models.DateField(null=True, blank=True)
class Person(models.Model):
first_name = models.CharField(max_length=15, default='')
surname = models.CharField(max_length=30, default='')
def __unicode__ (self):
return self.first_name + ' ' + self.surname
这是错误的方法吗?
答案 0 :(得分:2)
这里不需要隐藏的字段。将该字段保留在模型表单之外:
class Model1Form(forms.ModelForm):
class Meta:
model = Model1
fields = ['start_date', 'end_date']
然后在您的视图中,使用commit=False
保存,然后在实例上设置person
。
if request.method == "POST":
model1form = Model1Form(request.POST, request.FILES, user=request.user)
if model1form.is_valid(): # fails here
instance = model1form.save(commit=False)
instance.person = Person.objects.get(username_field=request.user)
instance.save()
有关详细信息,请参阅the docs on the model form's save()
method。
完成此更改后,您可能会发现可以从表单的user
方法中删除__init__
。
答案 1 :(得分:0)
首先让我们改变你的模型
class Model1(models.Model):
person = models.ForeignKey(Person, null=True)
start_date = models.DateField(null=True, blank=True)
end_date = models.DateField(null=True, blank=True)
以前你有person_id
作为外键,这意味着你会有一个字段person_id_id
,这很难读。
现在为表格。您需要确保您的fk是已清理数据的一部分。
class Model1Form(forms.ModelForm):
class Meta:
model = Model1
fields = ['start_date', 'end_date']
...
def clean(self):
cleaned_data = super(Model1Form, self).clean()
...
username = self.user
person = Person.objects.get(username_field=username)
cleaned_data["person_id"] = person.id
# if that doesn't work try cleaned_data["person"] = person
...
return cleaned_data