我试图根据一些3路关系逻辑过滤m-2-m。我有以下模型(仅限示例......但我写的越多,它看起来就像我想玩的游戏......)原谅我过度使用spam
和eggs
元变量...
class SuperProfile(models.Model):
user = models.ForgeignKey('User')
eggs_unlocked = models.ManyToMany('Egg')
my_kitchen = models.ForeignKey('SuperKitchen')
class SuperKitchen(models.Model):
name = models.CharField(max_length=20)
class Egg(models.Model):
eggyness = models.PostiveIntegerField(help_text=_("how Eggy it is. eg."
"Spam'n'Eggs is over 9000")
kitchens = models.ForeignKey(help_text=_('What kitchen carries this')
eggs
列出他们可以使用的kitchen
Kitchen
永远不会改变。 Eggs
仅出现在一个kitchen
。SuperProfile
或SuperKitchen
的实例来过滤其他用户的Egg
列表 我不确定这是否清楚,请评论需要澄清的内容。
答案 0 :(得分:2)
在EggAdmin
中,您必须覆盖queryset
方法
class EggAdmin(admin.ModelAdmin):
...
def queryset(self, request):
kitchen = request.user.superprofile_set.get().my_kitchen #get related users kitchen
qs = super(EggAdmin, self).queryset(request) #call original queryset method that you are overriding
return qs.filter(kitchens=kitchen) #apply your filter
更新:好的,改变一切......在SuperPrifile管理员上,当你打开一个SuperProfile记录时,你希望根据该用户过滤eggs_unlocked
......所以:
import re
# grab the superprofile id from the url
sup_pro_rgx=re.compile(r'(\d+)')
sup_pro = sup_pro_rgx.findall(request.META['REQUEST_URI'])[0]
# I know this is really the ugliest way to do this, but there is no other way (at least as far as i know) to do this
class SuperProfileAdmin(admin.ModelAdmin):
...
def formfield_for_manytomany(self, db_field, request, **kwargs):
if db_field.name == "eggs_unlocked":
my_kitchen = self.get_object(request, object_id=sup_pro).my_kitchen
kwargs["queryset"] = Egg.objects.filter(kitchen=my_kitchen)
return super(SuperProfileAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
我知道,使用正则表达式获取对象ID是一种非常糟糕的做法,但正如我所提到的,这是我知道的唯一方法。
的文档答案 1 :(得分:0)
Eggs.objects.filter(kitchens=profile.my_kitchen)