如何在下拉模型表单字段中循环以仅在Django

时间:2018-05-09 22:29:18

标签: python django python-3.x django-forms django-templates

我有4个选择

target = (('Week', 'Weekly target'),
          ('Day', 'Daily target'),
          ('Verify', 'Verify'),
          ('Done', 'Done'))

这是我实施选择的模型:

class GoalStatus(models.Model):

    target = models.CharField(max_length=100, choices=target, default="Week")
    name = models.ForeignKey(ScrummyUser, on_delete=models.CASCADE)
    goal_status = models.ForeignKey(ScrummyGoals, on_delete=models.CASCADE)

这是我的模型表格

class ChangeTaskForm(forms.ModelForm):

    class Meta:
        model = GoalStatus
        fields = '__all__'

这是我的html文件

{% if user.is_authenticated %}
{% if request.user|has_group:"ADMIN" %}

    <form action="{% url 'myapp:move_goal' %}"  method="post">
        {% csrf_token %}
        {% for field in form.data.target %}
            {% for foo in field %}
                {% if foo == Day %}
                    {{ foo }}
                {% endif %}
            {% endfor %}

        {% endfor %}
    </form>

如何遍历表单中的下拉列表,只显示所需的选项,比如说&#39; Day&#39;对于有权仅选择&#39; Day&#39;的用户。我是Django的新手。

2 个答案:

答案 0 :(得分:2)

在将表单发送到模板之前,所有逻辑都可以在后端(your views)完成:

if request.user.groups.filter(name__iexact="ADMIN").exists():
    form.fields['target'].choices = ( ('Day', 'Daily target'))

由于您正在使用Django CBV,请覆盖get_form()方法

def get_form(self, *args, **kwargs):
    form = super(ClassBasedView, self).get_form(*args, **kwargs)
    if self.request.user.groups.filter(name__iexact="ADMIN").exists():
        form.fields['target'].choices = ( ('Day', 'Daily target'))
    return form

答案 1 :(得分:0)

您可以修改ModelForm(ModelForm documentation here)中的选项。

以您的形式:

from ____ import target # idk where your target variable is but it needs to be visible to your ChangeTaskForm in here. So you may have to import it.

class ChangeTaskForm(forms.ModelForm):

    class Meta:
        model = GoalStatus
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super(ChangeTaskForm, self).__init__(*args, **kwargs)
        self.initialize_widgets()

    def initialize_widgets(self):
        """
        Initializes widgets for the form. This is not a built in
        method. It's a method I'm adding. You can manipulate any field 
        in the form along with their widgets. This is where the choices 
        can be filtered down from the overall choices to specific 
        choices.
        """
        target_choices_for_field = []
        for target_option_tuple in target: # loop through each option.
            can_choose_option = ... # This is where you do the logic to determine whether or not the option should be available.
            if can_choose_option:
                target_choices_for_field.append(target_option_tuple)
        self.fields["target"].widget = forms.Select(choices=target_choices_for_field)

然后,在你的html中:

{% if user.is_authenticated %}
{% if request.user|has_group:"ADMIN" %}

<form action="{% url 'myapp:move_goal' %}"  method="post">
    {% csrf_token %}
    {% form %}
    <input type="submit" value="submit">Submit</input>
</form>

现在,ModelForm已经处理了过滤代码中的选项,因此您不需要在模板中对此进行任何操作。尽可能多地将这样的逻辑推向堆栈是一个好主意。因此,表单选择应该在表单类中设置,而不是模板。作为旁注,同样的事情(尽可能推动逻辑)应该通过验证完成。使用view decorators@user_passes_test来处理要进行身份验证的群组。