Как я могу выбрать, какой выбор отображать в поле формы 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