使用.extra()
尝试了解如何在QuerySet上使用Django Admin list_filter超过一天在AdAdmin中,我需要添加一个新列' ad_hist_status_id'从模型AdHist,所以我可以在SomeListFilter:
上使用这部分代码def queryset(self, request, queryset):
return queryset.filter(ad_hist_status_id=self.value())
看起来不可能。使用sql执行此操作非常简单:
select a.*, ah.ad_hist_status_id from ad_ad a
join ad_adhist ah on ah.ad_id = a.id
where
ah.datetime_end is null
order by a.id DESC
到目前为止,我无法在Django Admin中使用这个SomeListFilter,错误是:
FieldError at /admin/ad/ad/
Cannot resolve keyword 'ad_hist_status_id' into field.
Choices are: addetailscategories, address, adhist, adphotos,
adprice, adscheduleinfo, age, comment, county, county_id,
date_inserted, date_updated, description, district, district_id,
email, id, lat, lng, name, parish, parish_id, schedule_type,
schedule_type_id, telephone, title, user_inserted, user_inserted_id,
user_updated, user_updated_id
我的问题是,如何有效地向QuerySet添加新列,然后如何使用新列查询这个新的QuerySet?
我的代码的某些部分吼叫
模特:
class Ad(models.Model):
title = models.CharField(max_length=250)
name = models.CharField(max_length=100)
description = models.TextField()
age = models.IntegerField(blank=True, null=True)
telephone = models.CharField(max_length=25)
email = models.EmailField()
district = models.ForeignKey(District)
county = ChainedForeignKey(County, chained_field="district", chained_model_field="district", sort=True) # smart_selects app
parish = ChainedForeignKey(Parish, chained_field="county", chained_model_field="county", sort=True) # smart_selects app
address = models.CharField(max_length=250, null=True, blank=True)
lat = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
lng = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
schedule_type = models.ForeignKey(AdScheduleType)
comment = models.TextField(null=True, blank=True)
user_inserted = models.ForeignKey(User, null=True, blank=True, related_name='user_inserted_ad')
date_inserted = models.DateTimeField(auto_now_add=True)
user_updated = models.ForeignKey(User, null=True, blank=True, related_name='user_updated_ad')
date_updated = models.DateTimeField(null=True, blank=True)
def __str__(self):
return self.name
class AdHist(models.Model):
ad = models.ForeignKey(Ad)
datetime_begin = models.DateTimeField()
datetime_end = models.DateTimeField(null=True, blank=True)
ad_hist_status = models.ForeignKey(AdHistStatus)
ad_hist_change_reason = models.ForeignKey(AdHistChangeReason)
comment = models.TextField(null=True, blank=True)
user_inserted = models.ForeignKey(User, null=True, blank=True, related_name='user_inserted_ad_hist')
date_inserted = models.DateTimeField(auto_now_add=True)
user_updated = models.ForeignKey(User, null=True, blank=True, related_name='user_updated_ad_hist')
date_updated = models.DateTimeField(null=True, blank=True)
def __str__(self):
return self.ad.name
管理员:
class SomeListFilter(admin.SimpleListFilter):
title = _('Approval State')
parameter_name = 'ad_hist_status_id'
def lookups(self, request, model_admin):
return (
('1', _('Approved')),
('4', _('Not Approved')),
)
def queryset(self, request, queryset):
return queryset.filter(ad_hist_status_id=self.value())
class AdAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'title', 'age', 'telephone',
'email', 'district', 'county', 'parish',
'ad_status', 'ad_hist_change_reason', 'comment',
'user_inserted', 'date_inserted', 'user_updated',
'date_updated', 'ad_hist_status_id')
readonly_fields = ('ad_status', 'id', 'ad_hist_change_reason',
'ad_hist_status_id')
list_filter = (SomeListFilter,)
def get_queryset(self, request):
qs = super(AdAdmin,self).get_queryset(request).extra(select={'ad_hist_status_id': 'select ad_hist_status_id from ad_adhist where ad_adhist.ad_id = ad_ad.id and ad_adhist.datetime_end is null'},)
return qs
def ad_hist_status_id(self, inst):
return inst.ad_hist_status_id
有人能给我一些线索吗?
最好的问候
答案 0 :(得分:0)
如果我理解你的问题,你正在寻找:
from django.db.models import F
def queryset(self, request, queryset):
return queryset.filter(ad_hist_status__id=F('id'))
F expression用于引用同一模型中的字段,要引用相关模型中的字段,您需要使用下划线(__)。
答案 1 :(得分:0)
仔细看看Django field lookups。看看文档说的是什么:
基本查找关键字参数采用
field__lookuptype=value
形式。 (这是双下划线)。
您希望从AdHist
获取Ad
相关对象,该对象具有相关AdHistStatus
,并获取其id
。
因此,您应该访问此id
字段,如:
def ad_hist_status_id(self, instance):
return instance.adhist.ad_hist_status.id
或者您可以使用双下划线语法直接列出它:
class AdAdmin(admin.ModelAdmin):
list_display = (..., 'adhist__ad_hist_status__id')