Django ограничивает выбор внешнего ключа поля user на основе пользователя, который вошел в систему
У меня есть модель под названием Client с полем user в качестве внешнего ключа:
class Client(models.Model):
name = models.CharField(_('Client Name'), max_length=100)
address = models.CharField(_('Client Address'), max_length=100, blank=True)
demand = models.PositiveIntegerField(_('Client Demand'))
location = models.PointField(_('Client Location'))
created_at = models.DateTimeField(auto_now=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
class Meta:
default_permissions = ('add', 'change', 'delete', 'view')
def __str__(self):
return self.name
Я хочу ограничить выбор поля пользователя в форме администратора на основании того, кто вошел в систему
Например, здесь я вошел в систему под именем agung, поэтому я хочу, чтобы поле выбора пользователя ограничивалось только agung, но здесь я могу получить доступ к другим именам пользователей, таким как admin и rizky.
Я попробовал это
class ClientAdminForm(forms.ModelForm):
class Meta:
model = Client
fields = "__all__"
def __init__(self, request, *args, **kwargs):
super(ClientAdminForm, self).__init__(request, *args, **kwargs)
if self.instance:
self.fields['user'].queryset = request.user
но кажется, что он не может принять запрос в качестве аргумента (я полагаю, потому что это не Http запрос)
Вы можете сделать это, переопределив атрибут base_fields экземпляра вашей формы следующим образом :
views.py
# Before instantiate the form class
ClientAdminForm.base_fields['user'] = forms.ModelChoiceField(queryset=self.request.user)
# Now you can instantiate the form
form = ClientAdminForm(...)
NB : Делайте переопределение base_fields непосредственно перед инстанцированием формы
Вы можете переписать метод get_form
вашей Admin Model, чтобы добавить текущий request.user
в качестве свойства класса. Далее вы можете прочитать его в конструкторе формы и отфильтровать запрос.
class ClientAdmin(admin.ModelAdmin):
# [...]
def get_form(self, request, obj=None, **kwargs):
form_class = super(ClientAdmin, self).get_form(request, obj, **kwargs)
form_class.set_user(request.user)
return form_class
class ClientAdminForm(forms.ModelForm):
# [...]
@classmethod
def set_user(cls, user):
cls.__user = user
def __init__(self, *args, **kwargs):
super(ClientAdminForm, self).__init__(request, *args, **kwargs)
if self.instance:
self.fields['user'].queryset = \
self.fields['user'].queryset.filter(pk=self.__user.pk)
Однако, проще всего исключить это поле из формы и обновлять его в методе save_model
:
class ClientAdminForm(forms.ModelForm):
# [...]
def save_model(self, request, obj, form, change):
obj.user = request.user
obj.save()