Django 根据登录用户限制用户字段外键的选择
Django limit choice of user field foreign key based on the user that logged in
我有一个名为 Client 的模型,其中用户字段作为外键:
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,所以我希望 select 框选择用户字段限制为 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
但是好像不能接受request作为参数(我猜是因为这不是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(...)
注意: 在实例化表单之前重写 base_fields
您可以覆盖管理模型的 get_form
方法以将当前 request.user
添加为 class 属性。接下来您可以在表单的构造函数中读取它并过滤查询。
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__(*args, **kwargs)
self.fields['user'].queryset = \
self.fields['user'].queryset.filter(pk=self.__user.pk)
但是,最简单的方法是在表单中排除此字段并在 save_model
方法中更新它:
class ClientAdmin(admin.ModelAdmin):
# [...]
def save_model(self, request, obj, form, change):
obj.user = request.user
obj.save()
我有一个名为 Client 的模型,其中用户字段作为外键:
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,所以我希望 select 框选择用户字段限制为 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
但是好像不能接受request作为参数(我猜是因为这不是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(...)
注意: 在实例化表单之前重写 base_fields
您可以覆盖管理模型的 get_form
方法以将当前 request.user
添加为 class 属性。接下来您可以在表单的构造函数中读取它并过滤查询。
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__(*args, **kwargs)
self.fields['user'].queryset = \
self.fields['user'].queryset.filter(pk=self.__user.pk)
但是,最简单的方法是在表单中排除此字段并在 save_model
方法中更新它:
class ClientAdmin(admin.ModelAdmin):
# [...]
def save_model(self, request, obj, form, change):
obj.user = request.user
obj.save()