【问题标题】:How to set a custom queryset class for Django admin actions?如何为 Django 管理操作设置自定义查询集类?
【发布时间】:2016-05-23 23:48:48
【问题描述】:

在我正在构建的应用程序中,我创建了一系列自定义模型管理器和查询集以拥有更高级别的 api。

当我执行管理操作时出现问题。传递给它的查询集似乎是一个通用查询集,我希望能够访问我的自定义查询集,以便能够使用我在其中创建的过滤功能。

这是动作:

def mark_payment_as_sent_action():
    ''' Admin action to mark payment as sent '''

    def mark_payment_as_sent(modeladmin, request, queryset):

        # #####################################################################
        # This is what I currently do
        payments = queryset.filter(status=models.Payment.S_PENDING)

        # This is what I want to do
        payments = queryset.pending()
        # #####################################################################

        # Do stuff with filtered payments

        return HttpResponseRedirect("...")

    mark_payment_as_sent.short_description = "Mark as sent"
    return mark_payment_as_sent

这些是自定义模型管理器的一个查询集:

class PaymentQuerySet(models.query.QuerySet):

    def pending(self):
        return self.filter(status=self.model.S_PENDING)

class PaymentManager(models.Manager):
    use_for_related_fields = True

    def get_query_set(self):
        return PaymentQuerySet(self.model)

    def pending(self, *args, **kwargs):
        return self.get_query_set().pending(*args, **kwargs)

最后是模型和管理类:

class Payment(models.Model):

    status = models.CharField(
        max_length=25,
        choices=((S_PENDING, 'Pending'), ...)
    )

    objects = managers.PaymentManager()

@admin.register(models.Payment)
class PaymentsAdmin(admin.ModelAdmin):

    actions = (
        admin_actions.mark_payment_as_sent_action(),
    )

关于在调用管理操作时如何告诉 Django 使用我的查询集的任何提示?

非常感谢。

【问题讨论】:

  • 重写get_queryset 方法怎么样?
  • 哪一个? PaymentsAdmin 类?
  • 是的。此外,刚刚注意到您的经理中的 get_query_set 而不是 get_queryset。这可能是你的问题。
  • 这可能是个问题,谢谢指点。

标签: django django-models django-queryset django-admin-actions


【解决方案1】:

正如 noamk 所说,问题出在方法名称上。 Django 将get_query_set 方法重命名为get_queryset

现在它运行良好。

class PaymentQuerySet(models.query.QuerySet):

    def pending(self):
        return self.filter(status=self.model.S_PENDING)

class PaymentManager(models.Manager):
    use_for_related_fields = True

    def get_queryset(self):
        return PaymentQuerySet(self.model)

    def pending(self):
        return self.get_queryset().pending()

【讨论】:

    猜你喜欢
    • 2022-10-19
    • 2019-05-26
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    相关资源
    最近更新 更多