Django形成动态下拉列表创建

时间:2018-06-07 10:07:22

标签: django django-models django-forms

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

我最早请求你的帮助。

2 个答案:

答案 0 :(得分:1)

问题在于此处将参数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

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

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

答案 1 :(得分:1)

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

如果字段device_type是包含用户设备的模型的外键,我认为在视图中覆盖那些字段queryset要比使用表单init搞乱要容易得多。你可以这样做:

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

请注意,在调用RepairForm()时也无需传递submitted_by - 该字段已排除在表单上,​​并且您已经在{{1}内正确填充submitted_by字段阻止所以我不认为它能完成任何事情。

修改

views.py

if form.is_valid()

forms.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"})