Как я могу выбрать, какой выбор отображать в поле формы django?

Я пытаюсь динамически изменять просматриваемые варианты в поле выбора формы django в зависимости от пользователя. Вот моя форма:

SubmitForm(forms.ModelForm):
    class Meta:
        model = Lesson
        fields = (
            "status",
        )

Вот мой models.py для Lesson:

CLASS_STATUS = (
        ('Attended', 'Attended'),
        ('Absent', 'Absent'),
        ('Teacher Postponed', 'Teacher Postponed'),
        ('Student Postponed', 'Student Postponed'),
    )

    status = models.CharField(
        max_length=30,
        choices=CLASS_STATUS,
        null=True,
        blank=True,
    )

Итак, в основном я хочу иметь возможность выбирать, какие варианты показывать для каждого типа пользователей. Для этого, я надеюсь, вы также можете показать, как я могу получить доступ к request.user информации в моей форме. Спасибо, и, пожалуйста, задавайте мне любые вопросы, которые у вас есть.

Вот часть обзора, как просили некоторые из вас:

class SubmitView(generic.UpdateView):
    template_name = "agents/submit_form.html"
    queryset = Lesson.objects.all()
    context_object_name = "lesson"
    form_class = SubmitForm

Вам нужно будет динамически построить форму, поскольку представление имеет доступ к request.user, а предопределенная ModelForm - нет.

Поскольку вы используете представления на основе класса C, вы переопределите метод .get_form

Предоставленный метод (из приведенной выше ссылки) является

def get_form(self, form_class=None):
    """Return an instance of the form to be used in this view."""
    if form_class is None:
        form_class = self.get_form_class()
    return form_class(**self.get_form_kwargs())

Таким образом, ваша переопределение будет выглядеть примерно так

Нет, я неправильно понял, вы должны переопределить до того, как форма будет инстанцирована. Пересмотр в процессе ...

def get_form(self, form_class=None):

    form_instance = super().get_form( form_class)

    user = self.request.user
    # define choices based on user
    choices = ( (..., ...), ...)

    # I hope this will work with a ModelForm instance, have never tried 
    form_instance.fields['status'].choices = choices
    
    return form_instance

Если это не сработает, вам потребуется более серьезная переделка. Это, вероятно, означает, что ModelForm - это больше проблем, чем того стоит, и CBV может быть аналогичным. Напишите представление, используя обычную форму. Выполните выборку объекта и его обновление явно.

Или кто-то другой покажет нам, как динамически сузить класс ModelForm.Meta и класс ModelForm, использующий его, с выбором, подаваемым через его widgets={'status': ...}. Для меня это похоже на использование кувалды для раскалывания ореха (плюс я не знаю, как это сделать).

Я пытался и не смог заставить это работать с ModelForm. Я думаю, что лучшим решением будет вернуться к использованию ванильной формы и вручную обновлять объект. Что-то вроде

class Status_form( forms.Form):
    status = forms.ChoiceField( choices=Lesson.STATUS_CHOICES)

class UpdateLessonView( FormView):

    form_class = Status_form
    template_name = "agents/submit_form.html"

    def form_valid( self, form):
        self.lesson.status = form.cleaned_data['status']
        self.lesson.save()
        return redirect(
            'lessons:lesson_detail', lesson=self.lesson.pk )

    def get_form( self, form_class=None):
        self.lesson = get_object_or_404( Lesson, id=self.kwargs['lesson'] )
        self.initial = { 'status': self.wafer.status }
        form = super().get_form( form_class)

        # modify choices depending on user
        if self.request.user ... :

            status_choices=(   (..., ...), ... )

            form.fields['status'].choices = status_choices

    return form
Вернуться на верх