Django Python Формы - отправка сложного представления с несколькими формами и наборами форм - PullRequest
0 голосов
/ 06 апреля 2020

Представьте себе эту концепцию, у меня есть Такси, которое может быть заказано группой для нескольких посещений на целый день, и я должен назначить лидера группы для каждого бронирования. Теперь у меня есть резервирование ( PNR ), в котором содержится Клиенты Маршруты путешествий, и для этой брони назначен руководитель группы ( Оператор ).

На мой взгляд это:

  1. форма для выбора оператора
  2. для добавления набора клиентов

с этой точки зрения я пытаюсь упростить пользователю задачу, предоставив возможность сохранять каждую форму отдельно на ajax или сохранять все данные форм с помощью кнопки внизу представления.

I Я искал несколько дней, и я получил ближайший подход по этим двум ссылкам 1 & 2 , но все еще не могу заставить мой код работать правильно и делать то, что он должен делать , :( Любая поддержка будет высоко оценена!

My models.py :

class Operator (models.Model):
    name = models.CharField(max_length=50)
    # Other Fields

    def __str__(self):
        return self.code


class PNR (models.Model):
    date_created = models.DateTimeField(auto_now_add=True)
    # Other Fields

    def __str__(self):
        return self.pk


class Client (models.Model):
    related_pnr = models.ForeignKey(PNR, on_delete=models.CASCADE)
    name = models.CharField(max_length=200)
    # Other Fields

    def __str__(self):
        return self.related_pnr+" "+self.name

My forms.py :

class ChooseOperatorCode(forms.Form):
    operator = forms.ModelChoiceField(queryset=Operator.objects.all())

    def clean(self, *args, **kwargs):
        operator = self.cleaned_data.get('operator')

        return super(ChooseOperatorCode, self).clean(*args, **kwargs)


class NewClientForm(forms.Form):
    name = forms.CharField(widget=forms.TextInput(attrs={}), label=False, max_length=200)
    # Other Fields

    def clean(self, *args, **kwargs):
        name = self.cleaned_data.get('name')
        # Other Fields

        return super(NewClientForm, self).clean(*args, **kwargs)

My views.py :

@login_required
def create_pnr(request):

    pnr = PNR.objects.create(created_by_user=request.user)

    choose_operator_form = ChooseOperatorCode(request.POST or None)
    if choose_operator_form.is_valid():
        pnr.created_by_operator = choose_operator_form.cleaned_data.get('operator')
        pnr.save()
        choose_operator_form.save()

    clients_form = NewClientForm(request.POST or None)
    if clients_form.is_valid():
        client = Client()
        client.related_pnr = pnr.pk
        client.name = clients_form.cleaned_data.get('name')
        client.save()
        clients_form.save()
    context = {
        'pnr': pnr.pk,
        'choose_operator_form': choose_operator_form,
        'clients_form': clients_form,
    }
    return render(request, 'reservation_new.html', context)


@login_required
def edit_pnr(request, pnr_id):
    pnr = PNR.objects.get(id=pnr_id) 

    choose_operator_form = ChooseOperatorCode(request.POST or None)
    if choose_operator_form.is_valid():
        pnr.created_by_operator = choose_operator_form.cleaned_data.get('operator')
        pnr.save()

    clients_form = NewClientForm(request.POST or None)
    if clients_form.is_valid():
        client = Client()
        client.related_pnr = pnr.pk
        client.name = clients_form.cleaned_data.get('name')
        client.save()
        clients_form.save()
    context = {
        'pnr': pnr.pk,
        'choose_operator_form': choose_operator_form,
        'clients_form': clients_form,
    }
    return render(request, 'reservation_edit.html', context)

My url.py :

    path('operation/reservation/new/', views.create_pnr, name='new_pnr'),
    path('operation/reservation/existing/<int:pnr_id>/', views.edit_pnr, 
       name='existing_pnr'),

И, наконец, мой template. html: (для new и edit )

<form  method="POST" action="{% url 'existing_pnr' pnr_id=pnr %}" id="choose_operator_form">
     {% csrf_token %}
     {{choose_operator_form}}
</form>
<form  method="POST" action="{% url 'existing_pnr' pnr_id=pnr %}" id="clients_form">
     {% csrf_token %}
     {{clients_form}}
</form>
<script type="javascript">
    $(document).('submit', '#choose_operator_form', function(e){
        e.preventDefault();

        $.ajax({
            type:'POST',
            url:"{% url 'existing_pnr' %}",
            data: $('#choose_operator_form').serialize(),
            success: function (result) {
                // show success msg
            },
            error: function (data) {
                // show error msg
            }
        });
    });

    //same code for clients form
</script>

1 Ответ

1 голос
/ 07 апреля 2020

pnr не добавляется к объекту request, поэтому request.pnr не имеет смысла. Вам нужно передать id PNR через URL, чтобы к нему можно было получить доступ в представлении:

  • В urls.py, убедитесь, что URL для вашего edit_pnr view получает pnr_id: что-то вроде path('pnr/<int:pnr_id>/edit/', ..., name="existing_pnr").
  • В вашем шаблоне создайте URL для редактирования pnr следующим образом: {% url 'existing_pnr' pnr_id=pnr %}
  • По вашему мнению, получите pnr_id: def edit_pnr(request, pnr_id): ...

Теперь вы можете получить PNR, который редактируется следующим образом: pnr = get_object_or_404(PNR, pk=pnr_id), который будет правильно возвращать 404 Not Found, если кто-то попытается получить доступ к несуществующему PNR.

...