【问题标题】:Django forms dynamic dropdown list creationDjango表单动态下拉列表创建
【发布时间】:2018-11-17 05:01:41
【问题描述】:

models.py

在这里创建您的模型。

class DeviceType(models.Model):
    device_type = models.CharField(max_length=200,unique=True)

class Repair(models.Model):
    device_type                     = models.ForeignKey(DeviceType,to_field='device_type')
    submitted_by                    = models.ForeignKey(User,to_field='username')
    comments                        = models.TextField()
    repair_request_date             = models.DateField(default=datetime.now)
    repair_status                   = models.ForeignKey(RepairStatus, to_field="repair_status", null=True)
    repair_cost_estimate            = models.FloatField(null=True)

views.py

def repair_form(request):
    dlist = get_my_choices(request.user)
    if request.method == "POST":
        form = RepairForm(request.POST,device_type = dlist, submitted_by = request.user)
        #print(form)
        if form.is_valid():
            print("Inside repair form")
            post = form.save(commit=False)
            post.submitted_by = request.user
            print(post.pk)
            post.save()
            return redirect("RepairRequest")
    else:
        dlist = get_my_choices(request.user)
        print("Inside else of repair form")
        form = RepairForm( device_type = dlist, submitted_by = request.user)
        print("else form: ", form)
        return render(request, "Form_template.html", {"form": form,\
                                                      "name": "Repair Request Form"})

forms.py

class RepairForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        print("kwargs: ",kwargs)
        dlist = kwargs["device_type"]
        print("Inside init of RequestForm")
        super(RepairForm, self).__init__(*args, **kwargs)
        self.fields["device_type"] = forms.ChoiceField(choice = [dlist])
        self.fields["submitted_by"] = kwargs["submitted_by"]



    class Meta:
        print("Inside Meta of RepairForm")
        model = Repair
        print("model: ", model)
        fields = "__all__"
        print("fields: ", fields)
        exclude = ("repair_cost_estimate","repair_status","submitted_by","repair_request_date",)

我正在尝试在 django 表单中创建一个动态下拉列表。从下拉列表将仅填充与给定用户关联的数据的意义上说是动态的。就我而言,每个用户都可能随身携带一台笔记本电脑、鼠标等。我已经编写了上面显示的代码。每次执行代码时都会出现以下错误:

TypeError at /user_dashboard/RepairRequest.html
__init__() got an unexpected keyword argument 'submitted_by'
Request Method: GET
Request URL:    http://127.0.0.1:8000/user_dashboard/RepairRequest.html
Django Version: 1.11.13
Exception Type: TypeError
Exception Value:    
__init__() got an unexpected keyword argument 'submitted_by'
Exception Location: E:\inventory management\inventory_management_service\inventory_management_app\forms.py in __init__, line 15
Python Executable:  C:\Anaconda2\python.exe
Python Version: 2.7.14
Python Path:    
['E:\\inventory management\\inventory_management_service',
 'C:\\Anaconda2\\python27.zip',
 'C:\\Anaconda2\\DLLs',
 'C:\\Anaconda2\\lib',
 'C:\\Anaconda2\\lib\\plat-win',
 'C:\\Anaconda2\\lib\\lib-tk',
 'C:\\Anaconda2',
 'C:\\Users\\Jaimik Jain\\AppData\\Roaming\\Python\\Python27\\site-packages',
 'C:\\Anaconda2\\lib\\site-packages',
 'C:\\Anaconda2\\lib\\site-packages\\win32',
 'C:\\Anaconda2\\lib\\site-packages\\win32\\lib',
 'C:\\Anaconda2\\lib\\site-packages\\Pythonwin',
 'C:\\Anaconda2\\lib\\site-packages\\pywinpty-0.5-py2.7-win-amd64.egg']
Server time:    Thu, 7 Jun 2018 09:56:44 +0000

我最早请求您的帮助。

【问题讨论】:

  • 在调用super().__init__ 之前,您应该先pop submitted_by
  • 我弹出了这些值,但是,我收到了这个错误,“/user_dashboard/RepairRequest.html __init__() 的 TypeError 得到了一个意外的关键字参数 'choice'”。可能是什么原因? @WillemVanOnsem

标签: django django-models django-forms


【解决方案1】:

您的维修模型是什么样的?

如果字段device_type 是包含您的用户设备的模型的外键,我认为在您的视图中覆盖该字段查询集而不是弄乱表单初始化会容易得多。你可以这样做:

form = RepairForm()
form.fields['device_type'].queryset = MyDeviceModel.objects.filter(user=request.user)

请注意,在调用 RepairForm() 时也不需要传递 submit_by - 该字段被排除在表单本身中,并且您已经在处理您的 if form.is_valid() 块中正确填充 submitted_by 字段所以我不认为那是完成任何事情。

编辑

views.py

def repair_form(request):
    if request.method == "POST":
        form = RepairForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.submitted_by = request.user
            post.save()
            return redirect("RepairRequest")
    else:
       form = RepairForm()
       form.fields['device_type'].queryset = DeviceType.objects.filter(user=request.user)

       return render(request, "Form_template.html", {"form": form, "name": "Repair Request Form"})

forms.py

class RepairForm(forms.ModelForm):

   class Meta:
      model = Repair
      exclude = ( "repair_cost_estimate","repair_status","submitted_by","repair_request_date",)

【讨论】:

  • 这里的 MyDeviceModel 必须替换为我的数据库中存在的模型名称对吗? @WilliamShaw
  • 是的,正确,假设您的模型是这样设置的 - 如果您想将修复模型添加到原始帖子中,我可以提供进一步的帮助。
  • 已更新。 @WilliamShaw
  • 已更新。 @WilliamShaw
  • @AishwaryShukla 我已将我的答案编辑为适合您的观点和表格。请注意,我还删除了“fields = 'all',因为没有必要同时调用两个字段并排除。抱歉,如果格式/缩进略有偏差,我在移动设备上。我希望这会有所帮助。
【解决方案2】:

问题在于您将参数submitted_bydevice_type 传递给RepairForm 构造函数。由于您明确提到了这些,这意味着它们存储在 kwargs 字典中。

但是,在执行super().__init__(*args, **kwargs) 调用之前,您修改此字典。结果,超类ModelForm)也将接收这些参数,但它确实了解如何处理这些参数。结果会报错。

因此您需要从kwargs 中删除这些参数。例如.pop(..):

class RepairForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        dlist = kwargs.pop("device_type")
        submitted_by = kwargs.pop("submitted_by")
        super(RepairForm, self).__init__(*args, **kwargs)
        self.fields["device_type"] = forms.ChoiceField(choices=[dlist])
        self.fields["submitted_by"] = submitted_by

在初始化ChoiceField 时,您还应该使用choices=... 作为参数,而不是choice=...

我认为有多个额外的错误,但我希望这能提供一些好的方向。

【讨论】:

  • 非常感谢。它有所帮助,但是在更改代码后,我得到了这个:ValueError at /user_dashboard/RepairRequest.html too many values to unpack @WillemVanOnsem
  • @AishwaryShukla:是的,你可能应该写choices=dlist,而不是把它包装在一个额外的列表中。
  • 还是一样。 @WillemvanOnsem
  • @AishwaryShukla:我建议你检查 dlist 实际包含的内容。 choices 应该是 2 元组的可迭代对象:docs.djangoproject.com/en/2.0/ref/models/fields/#field-choices
  • choicefield 有哪些替代方案? @WillienVanOnsem
猜你喜欢
  • 2014-07-22
  • 2016-08-19
  • 2020-01-09
  • 2021-05-18
  • 1970-01-01
  • 1970-01-01
  • 2015-11-06
  • 2018-07-22
  • 1970-01-01
相关资源
最近更新 更多