【问题标题】:Django UpdateView: cannot get form fields to show database valuesDjango UpdateView:无法获取表单字段以显示数据库值
【发布时间】:2020-01-27 23:16:12
【问题描述】:

我找到了相同问题的多个答案,但不幸的是,我似乎无法弄清楚:(

表单在我的模型“PhysicalPart”中有一个“子类别”字段的下拉列表,“子类别”字段的值在表单创建时动态更新(使用“类别”参数)。

不幸的是,我无法让下拉菜单显示所有子类别AND同时选择数据库中的一个。我似乎也无法从数据库中检索到“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>

【问题讨论】:

  • 你能展示你的模型吗?
  • @BleuBizarre 我不认为这个问题与我的模型有关,它只是一堆 CharField(也是“子类别”)。
  • 为了能够理解您的模型。为什么您的子类别不是 ForeignKey?
  • 在您强制选择过滤器的那一刻,您确定这有效吗?也许尝试使用一些随机值来仔细检查这是否不是你什么都看不到的原因
  • ForeignKey > 允许您拥有 OneToMany 关系,基本上它将所需类别的 ID 存储在数据库中,但是当您在 django 中请求它时,它将直接是与此 ID 相关的对象跨度>

标签: python django django-views


【解决方案1】:

我的问题是我没有区分 UpdateView 类中的“GET”和“POST”调用,我试图在 post() 方法。我花了一段时间才弄清楚,但现在我认为这很清楚了。 我最初使用 get() 方法,但我意识到 get_context_data() 更适合,因为它会自动加载大部分上下文(例如实例和表单),而不必在 get() 方法中从头开始做所有事情。

浏览UpdateView 类here 的代码,似乎还需要将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)

【讨论】:

    【解决方案2】:

    据我了解,您正在尝试编辑实例。这就是你在 Django 中的做法,它应该使用正确的值自动填充你的输入:

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

    有关此答案的更多详细信息:how to edit model data using django forms

    如果您的模型已正确完成(使用关系),则您不需要为 Select 提供选项。

    【讨论】:

    • 在 UpdateView 类之外,你所说的工作正常。我也在这里尝试过,但是如果我将“form = super(PartUpdate, self).get_form(self.form_class)”替换为“form = PartForm(request.POST, instance=self.object)”,我会得到相同的结果...
    猜你喜欢
    • 2018-05-11
    • 2014-10-14
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    • 2021-11-25
    • 2021-09-25
    • 2013-10-15
    • 1970-01-01
    相关资源
    最近更新 更多