Django Admin 中的 QuerySet 混淆

Posted

技术标签:

【中文标题】Django Admin 中的 QuerySet 混淆【英文标题】:QuerySet confusion in Django Admin 【发布时间】:2013-05-05 17:06:58 【问题描述】:

对 Django/Python 非常陌生,在阅读了大量有关此问题的文档和帖子后,我遇到了难题……

所以我正在开发一个简单的 Django 应用程序,它有一个 SQLlite 数据库/名称和电子邮件地址表。我希望能够从管理面板发送电子邮件,并使用我为给定名称/地址组合选择的复选框中的名称和电子邮件地址。该表本身工作正常,因为我可以从我网站上的其他视图发送电子邮件。

我正在制定一个自定义管理操作来执行此操作,我认为这是解决此问题的正确方法...

我以为我理解了 queryset 参数的用途以及它的功能,但无论我做什么,我都会收到 'QuerySet' object has no attribute 'name' 错误。显然我不知道查询集在管理操作中是如何工作的。

from django.contrib import admin
from email_check.models import employeeEmail
from django.template import loader, Context
from django.core.mail import send_mail


class employeeEmail_Admin(admin.ModelAdmin):
    list_display = ('name', 'address')
    actions = ['resend_message']

    def resend_message(self, request, queryset):
        for employeeEmail.address in queryset:
            message = loader.get_template('email.txt')
            messageContext = Context(
                'name': queryset.name
            )
            send_mail('Test Subject Line', message.render(messageContext), 'me@test.com', [queryset.address],
                      fail_silently=False)

admin.site.register(employeeEmail, employeeEmail_Admin)

我意识到这有点含糊,但基本上我希望弄清楚如何从我的employeeEmail 模型/表中访问名称和地址属性,以便我可以从管理面板发送电子邮件。在我有 queryset.name[queryset.address] 的地方,这些只是示例占位符,因为我尝试了许多不同的事情但没有成功,我猜我离解决方案还很远。

【问题讨论】:

【参考方案1】:

Python for 循环的工作方式并不完全如此。你想要这样的东西:

    for employee in queryset:
        message = loader.get_template('email.txt')
        messageContext = Context(
            'name': employee.name
        )
        send_mail('Test Subject Line', message.render(messageContext), 'me@test.com', [employee.address],
                  fail_silently=False)

关键是查询集提供了您的employeeEmail 模型的多个实例。当您在查询集上运行 for 循环时,employee 按顺序绑定到它们中的每一个。

【讨论】:

是的!这非常有效!我对查询集的工作方式感到更加困惑,并且没有意识到我可以在循环/管理操作中使用employeeEmail.nameemployeeEmail.address。如果没有 for 循环,还有更好的方法吗? 您可以使用 send_mass_mail 而不是 send_mail 来节省一些时间,但在构建消息元组时会占用更多内存。只要您需要为每个收件人定制消息(添加他们的姓名等),我就没有看到避免 for 循环的好方法。如果每个人的消息都相同,您可以使用 values_list 查询批量提取电子邮件地址。 实际上,既然我已经检查了源代码而不仅仅是文档,我发现您可以使用一个惰性求值生成器,它返回一个元组来代替带有 send_mass_mail 的实际消息元组,这样可以节省额外的内存。除了在内部,send_mass_mail 无论如何都会从它们创建一个列表。我想它仍然可以为您节省一些记忆,但没有我最初想的那么多。

以上是关于Django Admin 中的 QuerySet 混淆的主要内容,如果未能解决你的问题,请参考以下文章

Django Admin Cookbook-8如何在Django admin中优化查询

Django-admin实现管理员或特定组或人员可访问数据

获取 Django 对象并将其返回包装在 QuerySet 中的函数?

在 django 模板中使用聚合 QuerySet 中的字段

Django 将日期时间序列化为 QuerySet/Dict 中的 json

QuerySet 中的 Django _set.all() 过滤器