Django: 如何清理用户列表
这是我出错的代码:
dashboard = Dashboard.objects.get(slug=slug)
users = User.objects.all() # list of users
for editor in dashboard.dashboardeditor_set.iterator:
users.remove(editor.user)
错误信息:
‘instancemethod’对象不可迭代
来自models.py文件:
class DashboardEditor(models.Model):
dashboard = models.ForeignKey(Dashboard)
user = models.ForeignKey(User)
有没有人能帮我想办法从所有用户的列表中去掉编辑者?
谢谢!:)
2 个回答
0
可以结合使用 values_list()
和 exclude()
来在一个查询中获取结果(里面有一个嵌套的 SELECT
):
dash = Dashboard.objects.get(slug=slug)
User.objects.exclude(id__in=dash.dashboardeditor_set.values_list('user', flat=True))
这会生成以下的 SQL 语句:
SELECT "auth_user"."id",
"auth_user"."username",
"auth_user"."first_name",
"auth_user"."last_name",
"auth_user"."email",
"auth_user"."password",
"auth_user"."is_staff",
"auth_user"."is_active",
"auth_user"."is_superuser",
"auth_user"."last_login",
"auth_user"."date_joined"
FROM "auth_user"
WHERE NOT ("auth_user"."id" IN
(SELECT U0."user_id"
FROM "dashboard_dashboardeditor" U0
WHERE U0."dashboard_id" = 1)) LIMIT 21 [0.68ms]
使用 iterator
的话,大约会触发 N+2 次查询,其中 N 是给定 Dashboard
的 DashboardEditor
的数量:
In [24]: users = list(User.objects.all())
SELECT "auth_user"."id",
"auth_user"."username",
"auth_user"."first_name",
"auth_user"."last_name",
"auth_user"."email",
"auth_user"."password",
"auth_user"."is_staff",
"auth_user"."is_active",
"auth_user"."is_superuser",
"auth_user"."last_login",
"auth_user"."date_joined"
FROM "auth_user" [0.40ms]
In [25]: for editor in dash.dashboardeditor_set.iterator():
....: users.remove(editor.user)
....:
SELECT "dashboard_dashboardeditor"."id",
"dashboard_dashboardeditor"."user_id",
"dashboard_dashboardeditor"."dashboard_id"
FROM "dashboard_dashboardeditor"
WHERE "dashboard_dashboardeditor"."dashboard_id" = 1 [0.15ms]
SELECT "auth_user"."id",
"auth_user"."username",
"auth_user"."first_name",
"auth_user"."last_name",
"auth_user"."email",
"auth_user"."password",
"auth_user"."is_staff",
"auth_user"."is_active",
"auth_user"."is_superuser",
"auth_user"."last_login",
"auth_user"."date_joined"
FROM "auth_user"
WHERE "auth_user"."id" = 2 [0.25ms]
SELECT "auth_user"."id",
"auth_user"."username",
"auth_user"."first_name",
"auth_user"."last_name",
"auth_user"."email",
"auth_user"."password",
"auth_user"."is_staff",
"auth_user"."is_active",
"auth_user"."is_superuser",
"auth_user"."last_login",
"auth_user"."date_joined"
FROM "auth_user"
WHERE "auth_user"."id" = 3 [0.24ms]
在这个例子中,有两个 DashboardEditor
,所以 ORM 运行了 4 次查询来获取非编辑用户的结果列表。
2
我猜从错误信息来看,你可能缺少了括号:
for editor in dashboard.dashboardeditor_set.iterator():
这是因为错误信息似乎暗示了iterator
是一个实例方法,所以你需要调用它才能得到真正的迭代器。