django_admin详解(3)

** 重写formfield_for_dbfield()和save_model()和get_queryset()方法**

1.formfield_for_dbfield()方法:

该方法主要用来针对不同的字段,不同的用户,过滤不同的选项

1
2
3
4
5
6
7
8
9
10
def formfield_for_dbfield(self, db_field, request, **kwargs):
"""根据不同用户筛选其对应的数据,重新生成modelform"""
# db_field.name 获取model的字段
# 查找出店家的所有信息
if db_field.name == 'store':
# 店家
user = User.objects.get(username=request.user.username)
shopper = Shoppers.shoppers_.get(user=user)
kwargs['queryset'] = Commodity.commodity_.filter(shopper=shopper)
return super().formfield_for_dbfield(db_field,request,**kwargs)

2.save_model()方法:

点击保存按钮,预填充某些字段,不需要让用户手动再次填写,比如预填充当前的用户等等。

1
2
3
4
5
6
7
8
9
10
def save_model(self, request, obj, form, change):
"""保存对象后的自动添加商铺和用户"""
# 使用多对一,1对1的select_related优化查询
# Commodity.commodity_.select_related('shopper__user')
# 使用多对多,1对多的prefetch_related优化查询
# Shoppers.shoppers_.prefetch_related('commodity__store')
# result = self.get_queryset(request).select_related('shopper__user').first()
obj.store = Shoppers.shoppers_.get(user=request.user).store
obj.shopper = request.user
super().save_model(request, obj, form, change)

3.get_queryset()方法:

该方法主要针对不同的用户展现数据。

1
2
3
4
5
6
7
8
  def get_queryset(self, request):
"""只显示当前用户名下的评论"""
# 如果指定了ordering,get_queryset中也需要重写
result = super().get_queryset(request).filter(shopper=request.user)
ordering = self.get_ordering(request)
if ordering:
result = result.order_by(*ordering)
return result

注:如果admin中有ordering,字段我们需要对查询机进行排序。

get_queryset()源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  def get_queryset(self, request):
"""
Return a QuerySet of all model instances that can be edited by the
admin site. This is used by changelist_view.
"""
# 获取默认管理员,一般为超级管理员的针对该模型的所有查询集
qs = self.model._default_manager.get_queryset()
# TODO: this should be handled by some parameter to the ChangeList.
# 针对默认管理者即超级管理员的数据进行排序
ordering = self.get_ordering(request)
# 如果ordering字段不为None的话,进行排序
if ordering:
qs = qs.order_by(*ordering)
return qs