Django - form_valid () против save () - PullRequest
0 голосов
/ 04 июля 2018

В формах django для сохранения других данных я обычно использую form_valid(), но также могу использовать save() метод formclass.

Сегодня я переопределил save() вместо form_valid(), и у меня возникла проблема с моим множеством полей.

При использовании значения многих полей не сохраняются, но когда я использую form_valid(), они начинают сохранять. Кто-нибудь может сказать мне причину и каковы различия между ними, какой метод наиболее удобен и в какой ситуации?

Вот мое переопределение метода save ():

class ProductCreateForm(forms.ModelForm):
    sizes = make_ajax_field(ProductCreateModel,'sizes','sizes')
    colours = make_ajax_field(ProductCreateModel,'colours','colours')

    class Meta:
        model = ProductCreateModel

        fields = ('title','category',
                    'regions',)

    def __init__(self,*args,**kwargs):
        self.request = kwargs.pop("request")
        super(ProductCreateForm, self).__init__(*args, **kwargs)

    def save(self):
        product = super(ProductCreateForm, self).save(commit=False)
        user =  self.request.user

        product.location = user.user_location
        product.save()
        return product

Когда я переопределяю метод form_valid ():

   def get_form_kwargs(self):
       kwargs = super(ProductCreateView,self).get_form_kwargs()
       kwargs.update({'request':self.request})
       return kwargs

   def form_valid(self, form):
       product = form.save(commit=False)
       user =  self.request.user
       form.instance.user = user
       form.instance.location = user.user_location
       form.save()
       return super(ProductCreateView, self).form_valid(form)

sizes, colours и regions являются полями m2m, как я упоминал, когда я переопределяю save() значения m2m не сохраняются, но когда я переопределяю form_valid, они начинают сохранять.

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Если вы сохраняете форму с помощью commit=False, вы должны вызвать метод save_m2m формы, чтобы сохранить данные многие-ко-многим. См. документы для получения дополнительной информации.

Если вы решите использовать метод form_valid, я бы изменил следующие вещи:

  • обновите экземпляр, возвращенный form.save(), и сохраните его, вместо повторного вызова form.save().
  • явно позвонить form.save_m2m()
  • возвращает ответ о перенаправлении вместо вызова super().form_valid() (который снова сохранит форму)

Сложив это вместе, вы получите:

def form_valid(self, form):
    product = form.save(commit=False)
    product.user =  self.request.user
    product.location.location = user.user_location
    product.save()
    form.save_m2m()
    return redirect('/success-url/')
0 голосов
/ 04 июля 2018

По поводу вашей проблемы с Manytomany, я думаю, это порядок, в котором они работают ... Form> Admin> Models, когда вы используете form_valid, это первое, что они делают перед проверкой других вещей в цепочке, в то время как использование save является последним, может быть, может быть потому что или другие вещи тоже ...

Лучший способ всегда использовать form_valid вместо raw save

form_valid сначала проверьте функцию Очистить, если есть какие-либо собственные ошибки проверки или пользовательские проверки, и только затем сохраните ваши модели

сохранить просто сохраните его без подтверждения, затем с вашей формой с вашими подтверждениями

Пример

from django import forms

class ContactForm(forms.Form):
    # Everything as before.
    ...

    def clean(self):
        cleaned_data = super().clean()
        cc_myself = cleaned_data.get("cc_myself")
        subject = cleaned_data.get("subject")

        if cc_myself and subject:
            # Only do something if both fields are valid so far.
            if "help" not in subject:
                raise forms.ValidationError(
                    "Did not send for 'help' in the subject despite "
                    "CC'ing yourself."
                )

Источник: https://docs.djangoproject.com/en/2.0/ref/forms/validation/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...