Django UpdateView: невозможно получить поля формы для отображения значений базы данных - PullRequest
0 голосов
/ 28 января 2020

Я нашел несколько ответов на одни и те же вопросы, но, к сожалению, не могу понять: (

В форме есть раскрывающийся список для поля «подкатегория» в моей модели PhysicalPart ', значения поля «подкатегория» обновляются динамически при создании формы (с использованием параметра «категория»).

К сожалению, я не могу получить раскрывающийся список для отображения всех подкатегорий И одновременно выбрал значение из базы данных. Кажется, я не могу извлечь значение 'short_description' из базы данных.

Раньше он работал до того, как я узнал о классе UpdateView и решил использовать его вместо ...

Любое понимание того, как обойти мою проблему, будет оценено!

forms.py

class PartForm(forms.ModelForm):
subcategory = forms.ChoiceField(choices=[])

class Meta:
    model = PhysicalPart
    fields = ['subcategory', 'short_description']

views.py

class PartUpdate(UpdateView):
model = PhysicalPart
template_name = 'part_update.html'
form_class = PartForm

def post(self, request, *args, **kwargs):
    # Load model instance
    self.object = self.get_object()
    # Load form
    form = super(PartUpdate, self).get_form(self.form_class)
    # Populating subcategory choices
    form.fields['subcategory'].choices = SubcategoryFilter[self.object.category]

    # Check if form valid and save data
    if form.is_valid():
        form.save()

        return redirect('part-list')

    # Update context before rendering
    context = self.get_context_data(**kwargs)
    context['part_id'] = self.object.pk
    context['part_category'] = self.object.category
    context['manufacturing_list'] = self.object.manufacturing.all()

    return render(request, self.template_name, context)

html

<form action="{% url 'part-update' pk=part_id category=part_category %}" method="post" style="display: inline">
    {% csrf_token %}
    <div class="form">
        <p class="font-weight-bold">Type</br>
        {{ form.subcategory }}
        </p>
    </div>
    <div class="form">
        <p class="font-weight-bold">Short Description</br>
        {{ form.short_description }}
        </p>
    </div>
    <button type="submit" class="btn btn-primary">Save</button>
</form>
<form action="{% url 'part-list' %}" style="display: inline">
    <button type="submit" class="btn btn-danger">Cancel</button>
</form>

Ответы [ 2 ]

0 голосов
/ 28 января 2020

Моя проблема заключалась в том, что я не делал различий между вызовами "GET" и "POST" в классе UpdateView , я пытался сделать все в методе post (), Мне потребовалось некоторое время, чтобы понять это, но теперь я думаю, что все ясно. Первоначально я использовал метод get () , но я понимаю, что get_context_data () лучше подходит, поскольку он автоматически загружает большую часть контекста (например, экземпляр и форму) вместо необходимость делать все с нуля в методе get () .

Очистка кода класса UpdateView здесь , также необходимо добавить ModelFormMixin в объявлении класса PartUpdate, так что метод get_context_data () автоматически загружает форму, связанную с целевой моделью / экземпляром (иначе, похоже, он этого не сделает).

Вот мой обновленный код views.py:

class PartUpdate(UpdateView, ModelFormMixin):
    model = PhysicalPart
    template_name = 'part_update.html'
    form_class = PartForm
    success_url = reverse_lazy('part-list')

    def get_context_data(self, **kwargs):
        # Load context from GET request
        context = super(PartUpdate, self).get_context_data(**kwargs)
        # Get id from PhysicalPart instance 
        context['part_id'] = self.object.id
        # Get category from PhysicalPart instance
        context['part_category'] = self.object.category
        # Add choices to form 'subcategory' field
        context['form'].fields['subcategory'].choices = SubcategoryFilter[self.object.category]

        # Return context to be used in form view
        return context

    def post(self, request, *args, **kwargs):
        # Get instance of PhysicalPart
        self.object = self.get_object()
        # Load form
        form = self.get_form()
        # Add choices to form 'subcategory' field
        form.fields['subcategory'].choices = SubcategoryFilter[self.object.category]
        # Check if form is valid and save PhysicalPart instance
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)
0 голосов
/ 28 января 2020

Насколько я понимаю, вы пытаетесь редактировать экземпляр. Вот как вы это делаете в Django, он должен автоматически заполнить ваши входные данные правильными значениями:

my_record = MyModel.objects.get(id=XXX)
form = MyModelForm(instance=my_record)

Подробнее об этом ответе: как редактировать данные модели, используя django формы

Если ваши модели выполнены правильно (с отношениями), вам не нужно предоставлять выбор для выбора.

...