Django - 如何在form_invalid()的情况下保留内联formset数据

时间:2015-08-09 12:07:15

标签: django django-crispy-forms inline-formset

我正在尝试使用crispy_forms创建一个表单来添加新的汽车广告。它有一个能够使用django内联formset添加汽车照片的字段集。它在form_valid的情况下效果很好 - 我的广告创建成功,但是如果是form_invalid(例如,错过了必填字段),我会在没有上传图像的情况下返回我的表单 - 清除图像字段集。如何保留formset数据? 这是我的代码:

models.py

class AdCar(CarEquipment, AdBase):
        """ Model of Car advertisements """
        car_brand = models.ForeignKey(CarBrand)
        car_model = models.ForeignKey(CarModel)
        launch_year = models.IntegerField(choices=LAUNCH_YEARS)
        state = models.IntegerField(choices=AUTO_STATE, default=None)
        ...

@python_2_unicode_compatible
class ProductImage(models.Model):
    product = models.ForeignKey(AdBase, related_name='images')
    src = models.ImageField(upload_to="photos")

    objects = ImageManager()

    class Meta:
        ordering = ['id']

    def __str__(self):
        return "{0}{1}".format(MEDIA_URL, self.src)

forms.py

class AddCarAdvertForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(AddCarAdvertForm, self).__init__(*args, **kwargs)
        self.fields['steer'].required = False
        self.fields['electric_windows_lift'].required = False
        try:
            self.fields['car_model'] = forms.ModelChoiceField(
                queryset=CarModel.objects.filter(brand=self.initial['car_brand']),
                label = 'Model'
            )
        except KeyError:
            pass
        self.helper = FormHelper()
        self.helper.form_tag = False
        # self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-xs-4'
        self.helper.field_class = 'col-xs-8'
        self.helper.layout = Layout(
            Div(
                Div('seller_city', css_class='col-xs-10 text-center', css_id='city_div'),
                Div(Div('car_brand', css_class='col-xs-6'), Div('car_model', css_class='col-xs-6',
                    css_id='car_model_div'))
    ...


class ImageForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.template = 'bootstrap/table_inline_formset.html'
        self.helper.layout = Layout(
            Field('src'),
        )
        super(ImageForm, self).__init__(*args, **kwargs)

    class Meta:
        model = ProductImage
        fields = ('src',)


AdInlineFormSet = forms.models.inlineformset_factory(AdCar, ProductImage, form=ImageForm)

views.py

class AddCarAdvertView(CreateView):
    template_name = 'ads/car_advert_form.html'
    success_url = reverse_lazy('ad_success')
    model = AdCar
    form_class = AddCarAdvertForm

    def get_initial(self):
        initial = {}
        if self.request.user.is_authenticated():
            initial['seller_email'] = self.request.user.email
            initial['seller_name'] = self.request.user.first_name
        try:
            initial['seller_city'] = self.request.session['city_id']
        except KeyError:
            pass
        try:
            initial['car_brand'] = self.request.session['ad_car_brand']
        except KeyError:
            pass
        return initial

    def get(self, request, *args, **kwargs):
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        img_form = AdInlineFormSet()
        return self.render_to_response(self.get_context_data(form=form, img_form=img_form))

    def post(self, request, *args, **kwargs):
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        img_form = AdInlineFormSet(self.request.POST, self.request.FILES)
        if (form.is_valid() and img_form.is_valid()):
            return self.form_valid(form, img_form)
        else :
            return self.form_invalid(form, img_form)        

    def form_valid(self, form, img_form):
        self.object = form.save()
        img_form.instance = self.object
        img_form.save()


    def form_invalid(self, form, img_form):
        return self.render_to_response(self.get_context_data(form=form, img_form=img_form))

模板

<form action="" method="post" class="form-horizontal" enctype="multipart/form-data">
    {% crispy form %}
    <div class="row">
        <div class="col-xs-10 col-xs-offset-1">
            <div class="panel panel-default">
              <div class="panel-heading" style="background-color:#D93832">
                <h2 class="panel-title" style="font-size:1.2em">Photo block</h2>
              </div>
              <div class="panel-body">
                {% crispy img_form img_form.form.helper %}
              </div>
            </div>
        </div>
    </div>

    <div class="text-center">
        <input id="submit-id-submit" class="btn btn-primary btn-lg" name="submit" type="submit" value="Save">
    </div>

</form>

0 个答案:

没有答案