本文介绍了继承Django ManyRelatedManager的子类ManyToManyField的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以将Django ManyRelatedManager又称为ManyToManyField 的子类?

Is there a way to Subclass a Django ManyRelatedManager a.k.a. ManyToManyField ?

目标是在通过 deleted = None 标志调用 ManyRelatedManager 时对所有相关模型进行预过滤.如果 deleted = None ,则它是有效的 Model .

The goal is to pre-filter all related models when calling the ManyRelatedManager by a flag of deleted=None. If deleted=None then it is a valid Model.

到目前为止,这是代码,但似乎不起作用.

So far, this is the code, but it doesn't seem to work.

class ExcludeDeletedManyToManyField(models.ManyToManyField):

    def get_queryset(self):
        qs = super(ExcludeDeletedManyToManyField, self).get_queryset()
        return qs.filter(deleted__isnull=True)


class SelfRefrencingModel(models.Model):

    children = ExcludeDeletedManyToManyField('self', blank=True,
        symmetrical=False, related_name='parents')

推荐答案

您可以创建 SelfRefrencingModel 的rel ="nofollow">代理模型,并覆盖默认的经理.然后在 ManyToManyField 中使用此代理模型.

You can create proxy model of SelfRefrencingModel and override the default manager. Then use this proxy model in ManyToManyField.

ManyToManyField 进行子类化将无济于事,因为对于产生的查询集 ManyRelatedManger 是负责的.

Subclassing ManyToManyField will not help you because for the resulting queryset ManyRelatedManger is responsible.

代理模型方法:

from django.db import models

class A(models.Model):
    children = models.ManyToManyField('AProxy')
    name = models.TextField()
    deleted = models.NullBooleanField(null=True)


class FilterDeletedManager(models.Manager):
    def get_queryset(self):
        qs = super(FilterDeletedManager, self).get_query_set()
        return qs.filter(deleted__isnull=True)


class AProxy(A):
    objects = FilterDeletedManager()
    class Meta:
        proxy = True

使用这种方法的注意事项是,现在django希望 children 字段使用 AProxy 实例.

Caveat with this approach is that now django expects AProxy instances for children field.

因此,更好的可读性和可维护性的方法是在 __ init __ 中添加另一个属性.

So maybe better readable and maintainable approach will be to add another attribute in __init__.

from django.db import models

class A(models.Model):
    children = models.ManyToManyField('self')
    name = models.TextField()
    deleted = models.NullBooleanField(null=True)

    def __init__(self, *args, **kwargs):
        super(A, self).__init__(*args, **kwargs)
        self.deleted_null_children = self.children.filter(deleted__isnull=True)

这篇关于继承Django ManyRelatedManager的子类ManyToManyField的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-24 15:09