Inline formset adding wrong form

2019-09-19 08:14发布

I have a form and two inline formsets.
When I want to add photo_form actually doctors_form is added, but if I swap photo_form fieldset and doctor_form fieldset in html - everything works perfectly! What magic is going on?!

forms.py

class InstitutionForm(forms.ModelForm):

    class Meta:
        model = Institution
        fields = '__all__'
        error_css_class = 'error'
        required_css_class = 'required'

    def __init__(self, *args, **kwargs):
        super(InstitutionForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = False

InstitutionDoctorsFormSet = inlineformset_factory(Institution, Doctor, form=InstitutionForm, extra=1)
InstitutionPhotosFromSet = inlineformset_factory(Institution, Photo, form=InstitutionForm,  extra=1)

views.py

def institution_create(request):
    if request.POST:
        form = InstitutionForm(request.POST, request.FILES)
        doctor_form = InstitutionDoctorsFormSet(request.POST, request.FILES)
        photo_form = InstitutionPhotosFormSet(request.POST, request.FILES)
        if form.is_valid() and doctor_form.is_valid() and photo_form.is_valid():
            form.save()
            doctor_form.instance = form.save()
            doctor_form.save()
            photo_form.instance = form.save()
            photo_form.save()
            return redirect('base:institutions_list')
    else:
        form = InstitutionForm()
        doctor_form = InstitutionDoctorsFormSet()
        photo_form = InstitutionPhotosFormSet()

    args = {}
    args.update(csrf(request))

    args['form'] = form
    args['doctor_form'] = doctor_form
    args['photo_form'] = photo_form
    full_name = request.user.username

    return render(request, 'base/create_institution.html', locals())

html

<form class="the_form" enctype="multipart/form-data" action="." method="post">
    {% csrf_token %}
    {% crispy form  %}
    {% wysiwyg_editor "id_services" %}
    {% wysiwyg_editor "id_license_text" %}
    {% wysiwyg_editor "id_schedule" %}
    <fieldset>
        <legend>Photos</legend>
        {{ photo_form.management_form }}
        {{ photo_form.non_form_errors }}
        {% for form in photo_form %}
            {{ form.id }}
            <div class="inline {{ photo_form.prefix }}">
                {% crispy form  %}
            </div>
        {% endfor %}
    </fieldset>
    <fieldset>
        <legend>Doctors</legend>
        {{ doctor_form.management_form }}
        {{ doctor_form.non_form_errors }}
        {% for form in doctor_form %}
            {{ form.id }}
            <div class="inline {{ doctor_form.prefix }}">
                 {% crispy form  %}
            <br/>
            <br/>
            </div>
        {% endfor %}
    </fieldset>
    <div class="text-center">
        <input class="btn btn-default" type="submit" name="submit" value="Создать"/>
        <a class="btn btn-danger" href="/home/">Cancel</a>
    </div>
</form>

I tried to remove crispy form usage, but everythings is left same.

Update:

class Institution(models.Model):
    category = models.ForeignKey(Category, verbose_name="Категория")
    logo = ResizedImageField(size=[320, 320], crop=['middle', 'center'], quality=90, upload_to='logos', verbose_name="Логотип")
    name = models.CharField(max_length=255, verbose_name="Название")
    short_description = models.CharField(max_length=255, verbose_name="Описание")
    services = models.TextField(verbose_name="Услуги")
    license_text = models.TextField(blank=True, verbose_name="Лицензия")
    license_photo = models.ImageField(blank=True, verbose_name="Фото лицензии")
    actions = models.CharField(max_length=255, verbose_name="Акции")
    schedule = models.TextField(max_length=255, verbose_name="Расписание")
    phone = models.CharField(max_length=255, verbose_name="Телефон")
    email = models.CharField(max_length=255, verbose_name="Почта")
    address = models.CharField(max_length=255, verbose_name="Адрес")
    coordinates = models.CharField(default="", max_length=255, verbose_name="Координаты")
    website = models.CharField(max_length=255, verbose_name="Сайт")

    class Meta:
        verbose_name = u"Заведение"
        verbose_name_plural = u"Заведения"

    def __unicode__(self):
        return self.name

class Photo(models.Model):
    photo = ResizedImageField(size=[600, 600], crop=['middle', 'center'], quality=90, upload_to='institution_photos', verbose_name="Фото")
    rel_institution = models.ForeignKey(Institution)

    class Meta:
        verbose_name = u"Фото"
        verbose_name_plural = u"Фото"



class Doctor(models.Model):
    name = models.CharField(max_length=255, verbose_name="ФИО")
    doctor_photo = ResizedImageField(size=[400, 600], crop=['middle', 'center'], quality=90, upload_to='doctors_photos', verbose_name="Фото")
    specs = models.CharField(max_length=1000, verbose_name="Специализация")
    experience = models.CharField(max_length=255, verbose_name="Стаж работы")
    regime = models.TextField(default="", verbose_name="Режим работы")
    doctor_to_home = models.BooleanField(verbose_name="Возможность вызова на дом")
    rel_institution = models.ForeignKey(Institution)

    class Meta:
        verbose_name = u"Врач"
        verbose_name_plural = u"Врачи"

    def __unicode__(self):
        return self.name

2条回答
Luminary・发光体
2楼-- · 2019-09-19 08:30
if form.is_valid() and doctor_form.is_valid() and photo_form.is_valid():
    obj = form.save()

    doctor_form.instance = obj
    doctor_form.save()

    photo_form.instance = obj
    photo_form.save()

    return redirect('base:institutions_list')
查看更多
【Aperson】
3楼-- · 2019-09-19 08:38

I found a problem. It was in script. There was no formCssClass parameter.
So the script should look like this:

<script type="text/javascript">
    $(function () {
        $(".inline.{{ doctor_form.prefix }}").formset({
            prefix: "{{ doctor_form.prefix }}",
            formCssClass: 'dynamic-formset1'
        });
        $(".inline.{{ photo_form.prefix }}").formset({
            prefix: "{{ photo_form.prefix }}",
            formCssClass: 'dynamic-formset2'
        })
    })
</script>
查看更多
登录 后发表回答