我在同一个视图中有两个ModelForm对象 - Person和Adress。用户有界后,我正在保存Person对象。保存后,我想使用该保存的对象来设置AdressForm的ForeignKey,验证该表单并保存。我怎么设置这个?我的意思是ModelForm()中的字段?我到处搜索,并且说我必须保存(commit = False),但是我无法保存未经验证的表单!当我有效()时,有空白的ForeignKey字段!这是我的代码: (我尽量避免创建方法,而是保存)
views.py
class KontrahentCreate(LoginRequiredMixin, generic.View):
template = 'escrm/kontrahent_form.html'
context = dict()
message = "Utworzono pomyślnie nowego kontrahenta"
def get(self, request):
self.context['form_kontrahent'] = KontrahentForm(initial={'czy_aktywny': True})
self.context['form_kontrahent'].fields['czy_aktywny'].widget = HiddenInput()
self.context['form_adres'] = AdresKontrahentForm(initial={'czy_domyslny': True})
self.context['form_adres'].fields['czy_domyslny'].widget = HiddenInput()
self.context['title'] = 'Dodaj nowego kontrahenta'
return render(request, self.template, self.context)
def post(self, request):
kontrahent_form = KontrahentForm(request.POST)
adres_form = AdresKontrahentForm(request.POST)
if kontrahent_form.is_valid():
kontrahent = kontrahent_form.save()
else:
self.context['form_kontrahent'] = kontrahent_form
return render(request, self.template, self.context)
adres_form['kontrahent'].data = kontrahent.pk #AttributeError can't set attribute
if adres_form.is_valid():
adres_form.save()
else:
self.context['form_adres'] = adres_form
return render(request, self.template, self.context)
messages.success(self.request, self.message)
return HttpResponseRedirect(reverse_lazy('escrm:kontarhent-detail', kwargs={'pk': kontrahent.pk}))
forms.py
class KontrahentForm(ModelForm):
class Meta(ModelForm):
model = Kontrahent
fields = '__all__'
class AdresKontrahentForm(ModelForm):
class Meta(ModelForm):
model = AdresKontrahent
fields = '__all__'
widgets = {
'kontrahent': forms.HiddenInput(),
}
答案 0 :(得分:1)
在所有使用save(commit=False)
的地方,他们还会说您应该从表单中排除字段,而不是使用fields = '__all__'
。这样,表格就无效了。
答案 1 :(得分:1)
您应该从adres表单中排除kontrahent
字段。那表格没有它就有效!我添加了一些其他修改(例如,不要使您的上下文成为类变量)。此外,对于您提供初始值和隐藏输入的其他字段,请考虑将它们从表单中完全排除。如果在模型中为它们指定默认值,则也可以在视图中忽略它们:
class KontrahentForm(ModelForm):
class Meta(ModelForm):
model = Kontrahent
exclude = ['czy_aktywny'] # consider default value on model!
class AdresKontrahentForm(ModelForm):
class Meta(ModelForm):
model = AdresKontrahent
exclude = ['czy_domyslny', 'kontrahent']
# view
def get_form(self, formclass):
if request.method == 'POST':
return formclass(request.POST)
return formclass()
def get_context(self, **kwargs):
ctx = {}
ctx['form_kontrahent'] = kwargs.get('kontrahent_form', self.get_form(KontrahentForm))
ctx['form_adres'] = kwargs.get('adres_form', self.get_form(AdresKontrahentForm))
ctx['title'] = 'Dodaj nowego kontrahenta'
return ctx
def get(self, request):
return render(request, self.template, self.get_context())
def post(self, request):
kontrahent_form = self.get_form(KontrahentForm)
adres_form = self.get_form(AdresKontrahentForm)
k_valid = kontrahent_form.is_valid()
a_valid = adres_form.is_valid()
if not (k_valid and a_valid):
return render(
request, self.template,
self.get_context(kontrahent_form=kontrahent_form, adres_form=adres_form))
kontrahent = kontrahent_form.save(commit=False)
kontrahent.czy_aktywny = True
kontrahent.save()
adres = adres_form.save(commit=False)
adres.czy_domyslny = True
adres.kontrahent = kontrahent
adres.save()
messages.success(self.request, self.message)
return HttpResponseRedirect(reverse_lazy('escrm:kontarhent-detail', kwargs={'pk': kontrahent.pk}))