问题描述
有没有一种方法可以将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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!