Python 如何在“预回迁”相关的“管理列表”显示中获取自定义列的相关模型?
您好,我有两款通过第三款车型连接到m2m的车型:Python 如何在“预回迁”相关的“管理列表”显示中获取自定义列的相关模型?,python,django,django-admin,Python,Django,Django Admin,您好,我有两款通过第三款车型连接到m2m的车型: class Group(UsefulAbstractModel): hotels = models.ManyToManyField( Hotel, through='HotelDetails', related_name='groups', ) class Hotel(UsefulAbstractModel): name = models.CharField( ma
class Group(UsefulAbstractModel):
hotels = models.ManyToManyField(
Hotel,
through='HotelDetails',
related_name='groups', )
class Hotel(UsefulAbstractModel):
name = models.CharField(
max_length=255,)
class HotelDetails(models.Model):
hotel = models.ForeignKey(
Hotel,
related_name='hotel_details', )
group = models.ForeignKey(
Group,
related_name='hotel_details', )
num = models.IntegerField(
validators=[
MaxValueValidator(2),
MinValueValidator(1), ], )
所有团队都有两个编号为1和2的酒店链接。我需要显示在管理组界面它。
我为每个酒店创建两个自定义列:
class GroupAdmin(admin.ModelAdmin):
def first_hotel(self, instance):
return instance.hotel_details.filter(num=1).first().hotel
def second_hotel(self, instance):
return instance.hotel_details.filter(num=1).first().hotel
但对于每个实例,我现在都有两个额外的查询。我试图重写
queryset
方法,但没有得到帮助:
def queryset(self, request):
return super(GroupAdmin,self).queryset(request).prefetch_related('hotels')
问题是您正在使用
filter(num=1)
过滤预取的结果。这将导致Django执行新的查询
您可以使用预取
对象来获取正确的查询集。注意您应该重写模型管理员的方法,而不是queryset
def get_queryset(self, request):
return super(GroupAdmin,self).get_queryset(request).prefetch_related(
Prefetch('hotel_details', queryset=HotelDetails.objects.filter(num=1).select_related('hotel'), to_attr='hotel_details_num1'),
)
然后更改模型管理方法以使用新的queryset,例如:
def first_hotel(self, instance):
return instance.hotel_details_num1.first().hotel
有关
prefetch\u相关的和prefetch
对象的详细信息,请参阅。除非您计划添加编号为3、4等的酒店,否则使用两个外键Group.hotel1
和Group.hotel2
可能会更简单。@Alasdair是,这样可能会更好,节省我很多时间。但是这个项目几乎没有答案,但我有错误,因为实例
对象没有atribute,这是我们在预取
对象中定义的,我无法告诉你为什么会得到属性错误
。只要将queryset与预取
对象一起使用,就应该能够访问实例.hotel\u details\u num1
。我找到了解决方案。我使用方法get\u queryset
而不是queryset
,然后我更改select\u related
query,因为Prefetch
对象返回列表,而不是queryset,所以我直接将其放入queryset
atribute,就像这样:queryset=HotelDetails.objects.filter(num=1)。选择相关()
我不明白为什么queryset
方法不起作用,因为我使用的是1.8版本。谢谢你的帮助,请更新你的答案。很好,找出了错误,我已经修复了代码。我的答案。方法应该是get\u queryset
,如图所示-在那些文档中,只有queryset
方法用于SimpleListFilter
,这是一个不同的类。