django - 使用 Django 管理器按用户限制查询

  显示原文与译文双语对照的内容
0 0

假设我有两种类型的用户: 。

用户登录时,他应该只看到最近的10个条目。 用户登录时,他应该会看到最近的30个项目。 否则它们非常相似。

我相信可以使用 Django 管理器来实现这样的功能:

class Item(models.Model):
 name = models.CharField(max_length=200)
 date = models.DateField()
class BriefItemManager(models.Manager):
 def get_query_set(self):
 return super(BriefItemManager, self).get_query_set().order_by('date')[:10]
class LongItemManager(models.Manager):
 def get_query_set(self):
 return super(LongItemManager, self).get_query_set().order_by('date')[:30]

我正在考虑monkey补丁项目,也许使用中间件,这样剩下的代码就会忽略用户是一个的简短还是长。 在主代码启动时,对象的 manager manager manager manager manager manager manager manager manager manager manager或者 LongItemManager 。

if user_type(request.user) == 'brief':
 Item.objects = BriefItemManager()
else:
 Item.objects = LongItemManager()

问题:

  • 管理者是实现这个目标的正确方法?
  • 是monkeypatching项目 objects objects manager manager manager manager manager? 有没有更清晰的方法?
时间:原作者:1个回答

0 0

你不想 monkeypatch,因为创建 Item 类型后,它的状态在线程之间共享,它的中包括默认管理器。 然后,即使当前请求的用户为 long,因为在模型管理器上有线程争用,你可以能检索 10项。 ( 请参见软件包 django.db.models.base 中的ModelBase )

在你的情况下,你会想要明显的是你做了什么。 这是我最好的猜测

class ItemManager(models.Manager):
 def latest_for_user_type(user_type):
 limit = user_type=='brief' and 10 or user_type=='long' and 30
 return self.get_query_set().order_by('date')[:limit]
class Item(models.Model)
 #.. .
 objects = ItemManager()
# views.py
class LatestItemListView(ListView):
 def get_query_set(self):
 return Item.objects.latest_for_user_type(
 user_type=user_type(self.request.user)
 )

你可能希望在 ItemManager 中实现 user_type() 逻辑。 你甚至可能希望将它的重构为 latest_for_user(user=None, user_type=None) 这只是基本思想,还有其他方法,如代理类,是替代模型管理器的理想( true 路唯一的方法) 。

管理器是实现集合中任何操作的正确方法。

原作者:
...