Подтвердить что ты не робот

Создание форм джанго

Я изо всех сил пытаюсь разобраться в формах джанго. Я читал различные документы, но просто не могу понять понятия. Я должен разбираться с моделями, представлениями и шаблонами. Я пытаюсь создать форму с различными полями, составляющими раскрывающиеся списки и флажки, которые заполняются значениями в базе данных.

У меня есть рабочее приложение с именем vms. Используя models.py, у меня есть построенная простая схема, которая содержит размер и тип. Размер состоит из "малых", "средних" и "больших". Тип - это "окна" и "linux". Используя сайт администратора, я могу добавить дополнительный размер, например "Extra Large".

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

Я бы представил свои попытки кода, но на самом деле борюсь с концепциями. Может ли кто-нибудь помочь мне в том, как выполнить вышеуказанное?

Спасибо Oli

4b9b3361

Ответ 1

Формы - это просто инструмент для упрощения и ускорения процесса создания данных POST из запроса. Ручным способом было бы сделать request.POST.get('somefield') для всех полей, которые есть в некоторой HTML-форме. Но Django может сделать лучше, чем это...

По сути, класс Form содержит несколько полей и выполняет следующие задачи:

  • отображать входы HTML,
  • собирать и проверять данные, когда пользователь отправляет их,
  • Если поля не проверяются, возвращайте значения вместе с сообщениями об ошибках в HTML,
  • Если все поля проверяются, укажите form.cleaned_data словарь как удобный способ доступа к этим значениям в представлении.

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

Это означает, что в основном я мог бы сделать что-то вроде этого:
(простите меня за то, что я не тестировал этот код, поэтому я не могу ручаться, что он на 100% правильный)

models.py:

    class MyModel(models.Model):
        field1 = models.CharField(max_length=40, blank=False, null=False)
        field2 = models.CharField(max_length=60, blank=True, null=True)

forms.py:

    class FormForMyModel(forms.Form):
        form_field1 = forms.CharField(max_length=40, required=True)
        form_field2 = forms.CharField(max_length=60, required=False)

views.py:

    def create_a_my_model(request):
        if request.method == 'POST':
            form = FormForMyModel(request.POST)
            if form.is_valid():
                my_model = MyModel()
                my_model.field1 = form.cleaned_data.get('form_field1', 'default1')
                my_model.field2 = form.cleaned_data.get('form_field2', 'default2')
                my_model.save()
        else:        
            form = FormForMyModel()
        context_data = {'form': form}
        return HttpResponse('templtate.html', context_data)

(это может быть написано с несколькими строками кода меньше, но это должно быть как можно более ясным)

Обратите внимание, что нет никакой связи между полями модели и полями формы! Мы должны вручную назначать значения экземпляру MyModel при его создании.

В приведенном выше примере описывается общий рабочий процесс формы. Это часто необходимо в сложных ситуациях, но не в таком простом, как этот пример.

В этом примере (и много реальных примеров) Django может сделать лучше, чем это...

В приведенном выше примере вы можете заметить две неприятные проблемы:

  • Я должен определять поля на MyModel и поля на FormForMyModel отдельно. Тем не менее, существует много сходства между этими двумя группами (типами) полей, поэтому такая дублирующая работа. Сходство возрастает при добавлении меток, валидаторов и т.д.
  • Создание экземпляра MyModel немного глупо, нужно назначить все эти значения вручную.

Здесь находится ModelForm.

Они действуют в основном так же, как и обычная форма (на самом деле они расширены из обычных форм), но они могут спасти мне часть работы (две проблемы, которые я только что изложил, конечно:)).

Итак, вернемся к двум проблемам:

  • Вместо определения поля формы для каждого поля модели я просто определяю model = MyModel в классе Meta. Это инструктирует форму автоматически генерировать поля формы из полей модели.

  • Формы модели имеют доступный метод save. Это можно использовать для создания экземпляра модели в одной строке в представлении вместо того, чтобы вручную назначать поле за полем.

Итак, давайте сделаем пример выше с помощью ModelForm:

models.py:

    class MyModel(models.Model):
        field1 = models.CharField(max_length=40, blank=False, null=False)
        field2 = models.CharField(max_length=60, blank=True, null=True)

forms.py:

    class MyModelForm(forms.ModelForm):  # extending ModelForm, not Form as before
        class Meta:
            model = MyModel

views.py:

    def create_a_my_model(request):
        if request.method == 'POST':
            form = MyModelForm(request.POST)
            if form.is_valid():
                # save the model to database, directly from the form:
                my_model = form.save()  # reference to my_model is often not needed at all, a simple form.save() is ok
                # alternatively:
                # my_model = form.save(commit=False)  # create model, but don't save to database
                # my.model.something = whatever  # if I need to do something before saving it
                # my.model.save()
        else:        
            form = MyModelForm()
        context_data = {'form': form}
        return HttpResponse('templtate.html', context_data)

Надеемся, что это немного упростит использование форм Django.

Еще одно замечание - вполне нормально определять форму "Поля" на ModelForm. Они не будут использоваться в form.save(), но все равно могут быть доступны с помощью form.cleaned_data, как в обычной форме.

Ответ 2

Вы пробовали работать с ModelForms раньше? Насколько я понимаю, вы хотите создать форму на основе правильно созданной модели?

Допустим, ваша модель называется Temp. Вы можете создать форму, которая соотносится с этой моделью (и вашим вопросом) следующим образом:

forms.py

from django.forms import ModelForm

class TempForm(ModelForm):
  class Meta:
    model = Temp

ModelForm автоматически отобразит выбор/выбор из вашей модели в версию формы.

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

<form>
  <label for="id_size">Size</label>
  {{ form.size }}
</form>

Надеюсь, что ответит на ваш вопрос!