пытаюсь получить request.user, а затем запрос в форме, которая переопределяет ModelChoiceField и является подклассом

#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() это недопустимо… не уверен, что вы там имели в виду.