【问题标题】:Why isn't my ChoiceField rendering from my Django form onto the template?为什么我的 ChoiceField 没有从我的 Django 表单呈现到模板上?
【发布时间】:2021-09-08 19:21:35
【问题描述】:

我正在使用 django 表单并尝试呈现存储在字典键中的表单对象的名称,其对应的值存储一个 form.ChoiceField 以显示在网站上。出于某种原因,它仅显示内存中的对象位置,例如 而不是下拉列表本身。这些下拉列表只是从 0 到 N 的选择,其中 N 是数据库中可用项目的数量。

这是我的表单代码

    name = forms.CharField(label="Employee Name", max_length = 200, required = False)
    jobsite = forms.CharField(label="Jobsite", max_length = 200, required = True)
    date_needed = forms.DateField(initial = now, required = True)
    SundryFields = {}
    def __init__(self, *args, **kwargs):
        sundries = kwargs.pop('sundries')
        super(CreateNewOrder, self).__init__(*args, **kwargs) # ? it works i guess ? 
        for sundry in sundries:
            quantity_list = [(i, i) for i in range(sundry.quantity_available + 1)]
            self.SundryFields[sundry.name] = forms.ChoiceField(choices=quantity_list)

这是我的观点


```def orders(response):
    if response.method == "POST":
        form = CreateNewOrder(response.POST, sundries = Sundry.objects.all()) # holds information from form 
        if form.is_valid():

            cleaned_data = form.cleaned_data

            order = Order(name=cleaned_data["name"], jobsite=cleaned_data["jobsite"], date_needed=cleaned_data["date_needed"])
            order.save()
            # delete these from the order -- no longer needed once an order object is created 
            del cleaned_data["name"]
            del cleaned_data["jobsite"]
            del cleaned_data["date_needed"]

            # ROOM FOR OPTIMIZATION: filter data to only give list of objects that have a quantity requested with them
            def find_requested(cleaned_data):
                requested = []
                for name, value in cleaned_data.items():
                    if int(value) > 0:
                        requested.append(name)
                return requested

            # CREATE ALL ITEMS AND SAVE THEM TO THE ORDER
            for name in find_requested(cleaned_data):
                i = Item(order=order, text=name, quantity_requested=cleaned_data[name])
                i.save()
                # REMOVE FROM QUANTITY AVAILABLE IN SUNDRY MODEL
                Sundry.objects.filter(name=i.text).update(quantity_available = F('quantity_available') - i.quantity_requested)
            
            # HANDLE EMAILING HERE
            subject = 'QCE Warehouse - Order #' + str(order.pk)
            message = 'For: ' + order.name + "\n"
            for item in order.item_set.all():
                message += ("Item Requested: " + item.text + "Quantity: " + str(item.quantity_requested) + "\n")
            message += ("Date Needed: " + str(order.date_needed))
            email_from = settings.EMAIL_HOST_USER
            recipient_list = ['braxtonagoss@gmail.com']

            send_mail(subject, message, email_from, recipient_list)

            # SEND USER TO THANK YOU PAGE -- TODO: redirect to home after a few seconds
            return HttpResponseRedirect('thanks')

    else: 
        form = CreateNewOrder(sundries = Sundry.objects.all())

    return render(response, "main/order.html", {"sundryList": Sundry.objects.all, "form":form} )



这是模板


{% block title %}Orders{% endblock %}


{% block content %}
    
    <h1>Current List of Available Sundries</h1> 

    <form method = "post" action="/orders/"> 
        {% csrf_token %}
        <div class="mb-3"> 
            <ul>
            Name: {{form.name}}
            Jobsite: {{form.jobsite}}
            Date Needed: {{form.date_needed}}
            </ul>
        </div>

        <ul> 
        {% for key, val in form.SundryFields.items %}
            <li> {{key}}, {{val}}  </li> 
        {% endfor %}
        </ul>

        <button type="submit", name="submit"> Submit Order </button>
    </form>
    

{% endblock %}

【问题讨论】:

  • 在订单函数的else语句中,为什么form = CreateNewOrder(sundries = Sundry.objects.all())的那一行?
  • @FaisalNazik 因为我需要根据 **kwargs 中的杂项创建表单变量,所以我尝试将其删除并在 init 函数尝试获取时得到一个 imeediate keyError '杂货'。
  • 你想用这些sundryFields实现什么?
  • @WillemVanOnsem 我需要向用户显示的名称和下拉/输入框,以允许用户提交选择了这些数量的订单。

标签: python django django-forms


【解决方案1】:

如果我正确理解您的要求,您需要为 &lt;ul&gt; 中的每个 Sundry 对象渲染一个 &lt;select&gt; 字段?

如果您对每件商品有多种选择/可用数量,我建议您使用 &lt;input type="number" /&gt; 字段。

试试这个: 更改您的表单 init 以将计算得到的杂项名称和可用数量映射到键值对:

name = forms.CharField(label="Employee Name", max_length = 200, required = False)
jobsite = forms.CharField(label="Jobsite", max_length = 200, required = True)
date_needed = forms.DateField(initial = now, required = True)
SundryFields = {}
  def __init__(self, *args, **kwargs):
      sundries = kwargs.pop('sundries')
      super(CreateNewOrder, self).__init__(*args, **kwargs) # ? it works i guess ? 
      for sundry in sundries:
         self.SundryFields[sundry.name] = sundry.quantity_available
<ul> 
  {% for key, val in form.SundryFields.items %}
    <li>
      {{key}}  # This will display the current SundryItem description
      <input type="number" min="0" max="{{val}}"/> # the max number allowed is the sundry.quantity_available for this instance as specified in the form __init__
    </li> 
  {% endfor %}
</ul>

【讨论】:

  • 太棒了!奇迹般有效。如果我想添加引导程序并让它看起来不错,这会起作用吗?
  • 太棒了!高兴听到。是的,当然,使用引导程序,您只需将所需的类添加到
  • HTML 元素,当然还有所有其他需要样式的元素。它应该对您的业务逻辑没有影响。编码愉快!
  • 如果不介意还有一件事,表单现在不知道这些项目何时被选中,因此它永远不会将该信息发送到我的 view.py 文件。你知道我会怎么解决这个问题吗?
  • 所以你添加到输入字段的值永远不会像在views.py中声明的那样到达你的订单函数?您能否向该函数添加一些日志记录,以便我可以看到您得到了什么?你还有其他价值观吗? IE。姓名,工作地点?
  • 是的,经过测试的名称和工作地点会回到视图中,因为它们最终会出现在 views.py 发送的 emai 中。我在想我需要在我的 forms.py 中使用某种形式的 form.field() 但我不知道是哪种类型
  • 猜你喜欢
    相关资源
    最近更新 更多
    热门标签