これは少し複雑かもしれませんし、単に混乱しているかもしれません
1 ページに 2 つのフォームがあります。1 つはフォームで、もう 1 つはフォームセットです。私の目標は、フォームのフィールドに対してフォームセットのフィールドを検証することです。現在何が起こっているかについての私の推測は、プロジェクト フォーム ID をフォームセットに渡す方法が、フォームセットの検証のために選択されていない方法で発生していることです。
エラーが出ます
if target > project.target_date:
例外値: 'NoneType' オブジェクトには属性 'target_date' がありません
現在、検証なしで動作するコード: 注: マイルストーン モデルで null を許可するようにプロジェクトを設定しています。null を許可しない方がいいと思いますが、project_id を Milestones フォームに渡す方法を理解するには、これしか方法がありませんでした。
View.py
def ProjectAdd(request): #Finish the template
qs = Project.objects.none()
if request.method == 'POST':
form = ProjectAddForm(request.POST)
formset = MilestoneFormSet(request.POST)
if form.is_valid() and formset.is_valid():
project = form.save()
instances = formset.save(commit=False)
for instance in instances:
instance.project_id = project.id
instance.save()
return HttpResponseRedirect(reverse('project.views.detail', args=(project.id,)))
else:
form = ProjectAddForm()
formset = MilestoneFormSet(queryset=qs)
return render_to_response('project/addProjectForm.html', {
'form': form,
'formset': formset,
'current_date': current_date,
}, context_instance=RequestContext(request))
モデル.py
class Milestone(models.Model):
project = models.ForeignKey(Project, blank=True, null=True)
target_date = models.DateField('Target Date')
フォーム.py
MilestoneFormSet = modelformset_factory(Milestone, extra=1, max_num=50)
私が望むコードは検証で動作します。現在、forms.py 以外はすべて同じです。
フォーム.py
class MilestoneForm(forms.ModelForm):
def clean(self):
if any(self.errors):
raise forms.ValidationError("")
data = self.cleaned_data
target = data["target_date"]
project = data["project"]
if target > project.target_date:
raise forms.ValidationError("Target Date is beyond the project target date - Project Target: %s" % target)
if target < project.start_date:
raise forms.ValidationError("Target Date is before the start date of the project - Project Start: %s" % project.start_date)
return data
MilestoneFormSet = modelformset_factory(Milestone, form=MilestoneForm, extra=1, max_num=50)