Несколько Django форм в одном представлении: почему один POST очищает другие формы? - PullRequest
0 голосов
/ 14 января 2020

Я пытаюсь реализовать три формы на одной странице в Django. Каждая форма имеет собственную кнопку отправки, как показано в моем коде. Когда я отправляю данные в одну форму, данные сохраняются, но другие формы go остаются пустыми после полученного refre sh, и я получаю ошибку проверки в других формах, если поле, например, требуется.

Моя догадка заключается в том, что способ, которым Django обрабатывает POST и последующую ссылку на страницу sh, является причиной проблемы, и он пытается проверить все формы независимо от того, какую кнопку отправки я нажимаю. Я думал, что отображение названий кнопок, как показано, предотвратит это, но явно нет, и, возможно, мне придется обрабатывать каждую форму индивидуально с AJAX, чтобы решить эту проблему. Однако я не уверен, что это исправление, и мне бы понравилось, если бы кто-то мог пролить свет на то, что действительно происходит (то есть объяснить, что Django пытается сделать после отправки), чтобы я мог лучше понять, как решить. Любая помощь очень ценится. Обработка нескольких форм в одном представлении в Django совсем не прямолинейна.

Вот мой код:

Views.py

def update_machine_view(request, brand_name_slug, mclass_slug, profile_slug):

    machineentry = MachineEntry.objects.prefetch_related().select_related().get(profile_slug=profile_slug)

    f_plate         = PlateForm(request.POST or None, instance=machineentry.plate)
    f_dimensions    = DimensionsForm(request.POST or None, instance=machineentry.dimensions)
    f_chassis       = ChassisForm(request.POST or None, instance=machineentry.chassis)

    if request.method == 'POST' and 'save_plate' in request.POST:
        if f_plate.is_valid():
            f_plate.save()

    if request.method == 'POST' and 'save_dimensions' in request.POST:
        if f_dimensions.is_valid():
            f_dimensions.save()

    if request.method == 'POST' and 'save_chassis' in request.POST:
        if f_chassis.is_valid():
            f_chassis.save()


    context = {
        'f_plate': f_plate,
        'f_dimensions': f_dimensions,
        'f_chassis': f_chassis,
        'obj': machineentry,
    }

    return render(request, "machines/update_machine_form.html", context)

Шаблон :



<form method="post">
   {% csrf_token %}
   {{ f_plate | crispy }}
   <button type='submit' name='save_plate'>Save</button>
</form>
<form method="post">
   {% csrf_token %}
   {{ f_dimensions | crispy }}
   <button type='submit' name='save_dimensions'>Save</button>
</form>
<form method="post">
   {% csrf_token %}
   {{ f_chassis | crispy }}
   <button type='submit' name='save_chassis'>Save</button>
</form>

1 Ответ

1 голос
/ 14 января 2020

Что я могу понять, так это то, что вы передаете request.POST с каждой формой, даже не отправленной. Но в request.POST у вас есть значения для формы, которую вы отправили, а не другие. Следовательно ошибка показывает, что поле обязательно для заполнения. Я предлагаю вам сделать так:

def update_machine_view(request, brand_name_slug, mclass_slug, profile_slug):

    machineentry = MachineEntry.objects.select_related('plate', 'dimensions', 'chassis').get(profile_slug=profile_slug)

    f_plate         = PlateForm(instance=machineentry.plate)
    f_dimensions    = DimensionsForm(instance=machineentry.dimensions)
    f_chassis       = ChassisForm(instance=machineentry.chassis)

    if request.method == 'POST':
        if 'save_plate' in request.POST:
             f_plate = PlateForm(request.POST, instance=machineentry.plate)
             if f_plate.is_valid():
                 f_plate.save()

        if 'save_dimensions' in request.POST:
            f_dimensions = DimensionsForm(request.POST, instance=machineentry.dimensions)
            if f_dimensions.is_valid():
               f_dimensions.save()

        if 'save_chassis' in request.POST:
             f_chassis = ChassisForm(request.POST, instance=machineentry.chassis)
             if f_chassis.is_valid():
                  f_chassis.save()


    context = {
        'f_plate': f_plate,
        'f_dimensions': f_dimensions,
        'f_chassis': f_chassis,
        'obj': machineentry,
    }

    return render(request, "machines/update_machine_form.html", context)
...