【问题标题】:DJANGO select FORM that is from a generated list and add an extra default valueDJANGO 从生成的列表中选择 FORM 并添加一个额外的默认值
【发布时间】:2019-05-22 06:40:43
【问题描述】:

我想要一个选择下拉表单。在这个例子中,我希望有一个所有部门的下拉列表,但它可以包含一个额外的记录(默认 = 0)。

如何生成一个列表以选择并附加一个附加项目?

型号:

class Employee(models.Model):
    username = models.CharField(max_length=30, blank=False)  
    division = models.ForeignKey(Division,null=True)

class Division(models.Model):
    name_of_division = models.CharField(max_length=30)  

forms.py

class EmployeeEditForm(forms.ModelForm):   
    username = forms.CharField(max_length=30, required=True)    
    division = forms.ChoiceField(widget=forms.Select, choices=XXXXWHATSHOULDIPUTHEREXXX)

    class Meta:
        model = Employee
        fields = ("username","division")    

对于这个变量,我希望列表是这样的,但我不确定它应该如何编码:

XXXXWHATSHOULDIPUTHEREXXX = (0, Default) + Division.object.all()

例如,它应该生成如下内容:

division
0 - default (this is not in the Division table) <-- i want to add this to the select list
1 - corporate
4 - human resource
7 - engineering

【问题讨论】:

    标签: django list select django-forms


    【解决方案1】:

    您正在寻找ModelChoiceField 而不仅仅是ChoiceField

    class EmployeeEditForm(forms.ModelForm):   
        username = forms.CharField(max_length=30, required=True)    
        division = forms.ModelChoiceField(widget=forms.Select, queryset=Division.object.all(), empty_label="(Default)")
    
        class Meta:
            model = Employee
            fields = ("username","division")    
    

    如果您需要向表单传递附加值 - 表单本身无权访问请求对象,因此无法识别当前登录的用户。您的视图应该传递当前用户用户名:

    def index(request):
        # ...
        form = EmployeeEditForm(request.POST or None, company_id=request.user.employee.company.id)
        # ...
    
    class EmployeeEditForm(forms.ModelForm):   
        username = forms.CharField(max_length=30, required=True)    
        division = forms.ModelChoiceField(widget=forms.Select, queryset=None, empty_label="(Default)")
    
        class Meta:
            model = Employee
            fields = ("username","division")    
    
        def __init__(self, *args, **kwargs):
            company_id = kwargs.pop('company_id')
            super().__init__(*args, **kwargs)
            self.fields['division'].queryset = Division.objects.filter(company_id=company_id)
    

    不要将序列化的对象实例传递给表单 - 改用它们的 idpk 并通过 id 过滤表单中的查询集。

    【讨论】:

    • 实际上,使用 required=False 效果最好。那成功了。如果可以的话,还有一个问题,我如何将表单中的参数传递给过滤器?例如,queryset=Division.objects.filter(company=request.user.employee.company)
    【解决方案2】:

    我不确定这是否是您所追求的,但在 __init__ 中您可以指定空标签。

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['division'].empty_label = 'default'   
    

    【讨论】:

    • 我认为这不是我想要的,我对 XXXXWHATSHOULDIPUTHEREXXX 说得很清楚。不知道这应该是什么代码。
    • 您可以删除该行。你不需要它。然后它将拾取所有部门并添加默认值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-04
    • 2015-08-02
    • 2018-07-28
    • 1970-01-01
    相关资源
    最近更新 更多