Django表单 - 在modelForm保存

时间:2018-01-07 17:52:54

标签: python django django-forms

我在同一个视图中有两个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(),
        }

2 个答案:

答案 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}))