#django #django-forms
#django #django-forms
Вопрос:
Мне нужно передать переменную экземпляра (self.rank), которая будет использоваться переменной класса (provider) (см. закомментированную строку ниже).
Закомментированный, приведенный ниже код работает. Но я почти уверен, что мне все равно не следует пытаться передавать переменную экземпляра переменной класса. Итак, я ошеломлен тем, как достичь моей цели, которая заключается в динамической фильтрации моих данных в ModelChoiceField.
Как вы можете видеть, я уже переопределил ModelChoiceField, чтобы украсить имена пользователей. И я также сделал подкласс своей базовой формы подкачки, потому что у меня есть несколько других форм, которые я использую (здесь не показаны).
Еще один способ сказать , что мне нужно … Я хочу значение request.user в моей форме, чтобы затем я мог определить ранг этого пользователя, а затем отфильтровать своих пользователей по рангу, чтобы создать меньшее ModelChoiceField (это тоже выглядит хорошо). Обратите внимание, что в моем views.py я вызываю форму, используя:
form = NewSwapForm(request.user)
или
form = NewSwapForm(request.user, request.POST)
В forms.py:
from myapp.swaps.models import Swaps
from django.contrib.auth.models import User
class UserModelChoiceField(forms.ModelChoiceField):
""" Override the ModelChoiceField to display friendlier name """
def label_from_instance(self, obj):
return "%s" % (obj.get_full_name())
class SwapForm(forms.ModelForm):
""" Basic form from Swaps model. See inherited models below. """
class Meta:
model = Swaps
class NewSwapForm(SwapForm):
# Using a custom argument 'user'
def __init__(self, user, *args, **kwargs):
super(NewSwapForm, self).__init__(*args, **kwargs)
self.rank = User.objects.get(id=user.id).firefighter_rank_set.get().rank
provider = UserModelChoiceField(User.objects.all().
order_by('last_name').
filter(firefighter__hirestatus='active')
### .filter(firefighter_rank__rank=self.rank) ###
)
class Meta(SwapForm.Meta):
model = Swaps
fields = ['provider', 'date_swapped', 'swap_shift']
Спасибо!
Ответ №1:
Вы не можете сделать это таким образом, потому что self
на данный момент не существует — и даже если бы вы могли, это было бы выполнено во время определения, поэтому ранг был бы статичным для всех экземпляров формы.
Вместо этого сделайте это в __init__
:
provider = UserModelChoiceField(User.objects.none())
def __init__(self, user, *args, **kwargs):
super(NewSwapForm, self).__init__(*args, **kwargs)
rank = User.objects.get(id=user.id).firefighter_rank_set.get().rank # ??
self.fields['provider'].queryset = User.objects.order_by('last_name').filter(
firefighter__hirestatus='active', firefighter_rank__rank=rank)
Я поставил вопросительный знак рядом с rank
строкой, потому что rank_set.get()
это недопустимо… не уверен, что вы там имели в виду.