[英]How do I loop through a drop down model form field to display only some values in Django
I have 4 choices 我有4个选择
target = (('Week', 'Weekly target'),
('Day', 'Daily target'),
('Verify', 'Verify'),
('Done', 'Done'))
and this is my model to implement the choices: 这是我实现选择的模型:
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)
This is my Model form 这是我的模特表格
class ChangeTaskForm(forms.ModelForm):
class Meta:
model = GoalStatus
fields = '__all__'
and this is my html file 这是我的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>
How do I iterate through the drop down list in my form to display only a desired choice say 'Day' for a user that has permission to choose only 'Day'. 我如何遍历表单中的下拉列表,以仅向有权选择“天”的用户显示所需的选择,例如“天”。 I am very new to Django. 我是Django的新手。
All the logic can be done in backend ( your views
) before sending the form to template: 在将表单发送到模板之前,所有逻辑都可以在后端( your views
)中完成:
if request.user.groups.filter(name__iexact="ADMIN").exists():
form.fields['target'].choices = ( ('Day', 'Daily target'))
Since you're using Django CBV, override get_form()
method 由于您使用的是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
You can modify the choices in the ModelForm ( ModelForm documentation here ). 您可以在ModelForm( 此处的ModelForm文档 )中修改选择。
In your form: 以您的形式:
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)
Then, in your html: 然后,在您的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>
Now, the ModelForm has already dealt with filtering the options in the code so you don't need to do anything about that in the template. 现在,ModelForm已经处理了过滤代码中的选项,因此您无需在模板中对此做任何事情。 It's generally a good idea to push logic like that down the stack as much as possible. 通常最好将这样的逻辑尽可能往下推。 So form choices should be set in the form class, not the template. 因此,应该在表单类而不是模板中设置表单选择。 As a side note, the same thing (pushing logic as far down as possible) should be done with your validation. 附带说明一下,您的验证应执行相同的操作(将逻辑推得尽可能低)。 Use view decorators along with @user_passes_test to deal with groups to do authentication. 将视图修饰符与@user_passes_test一起使用以处理组以进行身份验证。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.