Как пройти через выпадающее поле формы модели для отображения только некоторых значений в Django - PullRequest
0 голосов
/ 10 мая 2018

У меня есть 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>

Как перебрать выпадающий список в моей форме, чтобы отобразить только желаемый вариант, скажем «День», для пользователя, который имеет право выбирать только «День».Я очень новичок в Джанго.

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Вы можете изменить выбор в ModelForm ( Документация ModelForm здесь ).

В вашей форме:

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 уже имеет дело с фильтрацией параметров в коде, поэтому вам не нужно ничего делать с этим в шаблоне. Как правило, неплохо бы как можно больше толкать подобную логику в стек. Таким образом, выбор формы должен быть установлен в классе формы, а не в шаблоне. В качестве примечания, то же самое (толкая логику как можно ниже) следует сделать с вашей проверкой. Используйте просмотр декораторов вместе с @ user_passes_test для работы с группами, выполняющими аутентификацию.

0 голосов
/ 10 мая 2018

Вся логика может быть выполнена в бэкэнде (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
...