子类Django ManyRelatedManager a.k.a. ManyToManyField

时间:2015-08-27 20:38:47

标签: python django

有没有办法 Subclass一个Django ManyRelatedManager a.k.a. ManyToManyField

目标是在通过ManyRelatedManager标志调用deleted=None时预过滤所有相关模型。如果是deleted=None,那么它是有效的Model

到目前为止,这是代码,但它似乎无法正常工作。

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')

3 个答案:

答案 0 :(得分:2)

您可以创建SelfRefrencingModel ManyToManyField并覆盖默认proxy model。然后在ManyToManyField中使用此代理模型。

子类ManyRelatedManger对您无济于事,因为生成的查询集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 负责。

代理模型方法:

AProxy

使用这种方法的警告是,现在django期望children字段的__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) 中添加另一个属性。

mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(Plus.API, options)
            .addScope(Plus.SCOPE_PLUS_LOGIN)
            .build();

答案 1 :(得分:0)

如果你打算在Django Admin或ModelForm中使用它;你不需要继承ManyToManyField。请参阅django documentation

class SelfRefrencingModel(models.Model):

    children = models.ManyToManyField('self', blank=True, symmetrical=False, 
        related_name='parents', limit_choices_to={'deleted': False}))

注意:如果deletedBooleanField,则必须是TrueFalse。它不能是None / NULL

beezz 使用代理模型的想法也很好。

我有时做的是自定义默认管理器
class MyModelManager(models.Manager):
    use_for_related_fields = True

    def get_queryset(self):
        qs = super(MyModelManager, self).get_queryset()
        return qs.filter(deleted=False)


class MyModelManager(models.Model):
    objects = MyModelManager()
    _objects = models.Manger()

    deleted = models.BooleanField(default=False)

默认情况下,deleted对象将被隐藏,但如果在查询集中需要它们,则可以使用_objects

答案 2 :(得分:0)

这是我的解决方案。 @beezz,使用代理模型来执行此操作可能是正确的,但我之前没有使用过代理模型这样的模式,所以这就是我解决这个问题的方法:

@Override
public void onStop() {
    super.onStop();

    // Free resources when not restarting, if API level is appropriate.
    if (Build.VERSION.SDK_INT >= 11 && !getActivity().isChangingConfigurations()) {
        freeResources();
    }
}