I would like to filter a queryset by a function in the model.
我希望通过模型中的一个函数过滤一个queryset。
class CommentAdmin(admin.ModelAdmin):
class PostedByGuestFilter(admin.SimpleListFilter):
title = 'Posted by Guest'
parameter_name = 'posted_by_guest'
def lookups(self, request, model_admin):
return (
(True, 'Yes'),
(False, 'No'),
)
def queryset(self, request, queryset):
if self.value():
return [comment for comment in queryset if comment.posted_by_guest()]
elif not self.value():
return [comment for comment in queryset if not comment.posted_by_guest()]
Unfortuneately, this implemenation results in django.admin
telling me that my database is corrupt. How can I fix this issue?
不幸的是,这种实现导致了django的出现。管理员告诉我我的数据库坏了。我该如何解决这个问题?
2 个解决方案
#1
1
The problem here is that Django is expecting a queryset and your code is providing a list. You can fix this by wrapping your comprehension in a set:
这里的问题是Django需要一个queryset,而您的代码提供了一个列表。你可以把你的理解用一个集合包装起来:
def queryset(self, request, queryset):
if self.value():
return set(comment for comment in queryset if comment.posted_by_guest())
elif not self.value():
return set(comment for comment in queryset if not comment.posted_by_guest())
#2
1
It’s not optimal (will result in an extra SQL query), and I’d be looking for ways to move the comment.posted_by_guest()
logic into SQL if possible (show the body of that method if you’d like help with that), but this ought to work:
它不是最优的(将导致额外的SQL查询),如果可能的话,我将寻找方法将comments .posted_by_guest()逻辑移动到SQL中(如果您愿意,请显示该方法的主体),但这应该是可行的:
def queryset(self, request, queryset):
expected_value = self.value()
excludes = []
for comment in queryset:
if comment.posted_by_guest() != expected_value:
excludes.append(comment.id)
return queryset.exclude(pk__in=excludes)
The Django admin filter API could do with some improvement!
Django管理过滤器API可以做一些改进!
#1
1
The problem here is that Django is expecting a queryset and your code is providing a list. You can fix this by wrapping your comprehension in a set:
这里的问题是Django需要一个queryset,而您的代码提供了一个列表。你可以把你的理解用一个集合包装起来:
def queryset(self, request, queryset):
if self.value():
return set(comment for comment in queryset if comment.posted_by_guest())
elif not self.value():
return set(comment for comment in queryset if not comment.posted_by_guest())
#2
1
It’s not optimal (will result in an extra SQL query), and I’d be looking for ways to move the comment.posted_by_guest()
logic into SQL if possible (show the body of that method if you’d like help with that), but this ought to work:
它不是最优的(将导致额外的SQL查询),如果可能的话,我将寻找方法将comments .posted_by_guest()逻辑移动到SQL中(如果您愿意,请显示该方法的主体),但这应该是可行的:
def queryset(self, request, queryset):
expected_value = self.value()
excludes = []
for comment in queryset:
if comment.posted_by_guest() != expected_value:
excludes.append(comment.id)
return queryset.exclude(pk__in=excludes)
The Django admin filter API could do with some improvement!
Django管理过滤器API可以做一些改进!