我有2个模型,作者和帖子,我怎样才能创建一个过滤器,谁可以在一行中选择每个作者的最后一个帖子(通过id字段?),对我来说不好的方法是:
authors = Author.objects.all()
queryset = []
for author in authors:
posts = Post.objects.filter(author=author).order_by('-id')
if loc:
queryset.append(posts[0])
具体来说,这是过滤我的Tastypie资源“PostResource”,这个过滤器只能给我每个用户的最后一个帖子,按创建排序
class LocationResource(ModelResource):
user = fields.ForeignKey(AccountResource,'user' )
class Meta:
queryset = Location.objects.all().order_by('-id')
resource_name = 'location'
#excludes = ['id',]
list_allowed_methods = ['post','get']
authentication = ApiKeyAuthentication()
authorization= Authorization()
filtering = {'user': ALL_WITH_RELATIONS}
def obj_create(self, bundle, **kwargs):
if bundle.request.method == 'POST':
return super(LocationResource, self).obj_create(bundle, user=bundle.request.user)
def apply_authorization_limits(self, request, object_list):
return object_list.filter(user=request.user)
def dehydrate(self, bundle):
return bundle
def build_filters(self, filters=None):
if filters is None: #if you don't pass any filters at all
filters = {}
orm_filters = super(LocationResource, self).build_filters(filters)
if('only_lasts' in filters):
query = filters['only_lasts']
sqs = Location.objects.values('user_id').annotate(max_id=models.Max('id')).values('max_id')
orm_filters["pk__in"] = sqs
return orm_filters
答案 0 :(得分:3)
阅读the blog post有关在SQL中按组获取最高行的信息。
如帖子中所述,您可以使用IN
或JOIN
。
以IN
为例:
SELECT * FROM post_table
WHERE id IN (SELECT MAX(id) AS max_id FROM post_table GROUP BY author_id);
SQL可以在QuerySet中编写为:
Post.objects.filter(pk__in=
Post.objects.order_by().values('author_id').annotate(
max_id=models.Max('id')).values('max_id'))
QuerySet
的{{1}}模式是:
SELECT MAX(id) AS max_id FROM post_table GROUP BY author_id
此外,您可以直接在Model.objects.order_by().values(...).annotate(foo=...).values('foo')
^------------^----------^-----------^-----------------^------------^
\ \ \ \ \
base queryset \ GROUP BY \ SELECT column
or manager remove possible annotation part
useless ordering Min/Max/...
中包装SQL。如果您选择queryset.raw()
版本,则JOIN
方式会更清晰。
请注意,.raw()
子句可能在数据库后端存在性能问题,如果性能至关重要,则需要分析和调整索引。
答案 1 :(得分:0)
a = Author.objects.get(pk=1)
#next line will give you the latest post of this particular author
latest_post = a.post_set.latest('id')