如何过滤多对多字段的模型?

时间:2016-06-10 14:59:51

标签: python django model many-to-many

我正在尝试为一队卡车实施地理围栏。我必须将边界列表与车辆相关联。除此之外,其中一个要求是,为了审计目的,删除所有内容甚至一旦删除。因此,我们必须对所有内容实施软删除。这就是问题所在。我的多对多字段不符合软删除管理器,它包括查找数据集中的活动和非活动记录。

class Vehicle(SoftDeleteModel):
    routes = models.ManyToManyField('RouteBoundary', through='VehicleBoundaryMap', verbose_name=_('routes'),
                                    limit_choices_to={'active': True})


class VehicleBoundaryMap(SoftDeleteModel):
    vehicle = models.ForeignKey(Vehicle, verbose_name="vehicle")
    route_boundary = models.ForeignKey(RouteBoundary, verbose_name="route boundary")
    # ... more stuff here

    alive = SoftDeleteManager()


class SoftDeleteManager(models.Manager):

    use_for_related_fields = True

    def get_queryset(self):
        return SoftDeleteQuerySet(self.model).filter(active=True)

如上所述,我试图确保默认管理器是一个软删除管理器(即仅用于活动记录的过滤器),并尝试使用limit limit_choices_to但结果只是对外部模型的字段而不是“直通”我想要的模特。如果您有任何建议或建议,我很乐意听取您的意见。

谢谢!

2 个答案:

答案 0 :(得分:5)

第一个问题:您使用limit_choices_to无法正常工作,因为documentation says

  在使用limit_choices_to参数指定的自定义中间表的ManyToManyField上使用时,

through无效。

您正在使用through,因此limit_choices_to无效。

第二个问题:使用use_for_related_fields = True也无效。 documentation说明了这个属性:

  

如果在模型的默认管理器上设置了此属性(在这些情况下仅考虑默认管理器),Django将在需要为类自动创建管理器时使用该类

您的自定义管理员已分配到alive的{​​{1}}属性而不是VehicleBoundaryMap,因此会被忽略。

我认为哪种方式可行:

  1. objects创建proxy model。我们称之为VehicleBoundaryMap。设置它以使其默认管理器为VehicleBoundaryMapProxy类似于:

    SoftDeleteManager()
  2. class VehicleBoundaryMapProxy(VehicleBoundaryMap): class Meta: proxy = True objects = SoftDeleteManager() 上有through='VehicleBounddaryMapProxy'

    ManyToManyField

答案 1 :(得分:1)

如果你这样做怎么办:

class Vehicle(SoftDeleteModel):
    #you can even remove that field
    #routes = models.ManyToManyField('RouteBoundary', through='VehicleBoundaryMap', verbose_name=_('routes'),
    #                                limit_choices_to={'active': True})

    @property
    def routes(self):
        return RouteBoundary.objects.filter(
            vehicleboundarymap__active=True,
            vehicleboundarymap__vehicle=self,
        )

现在而不是vehicle.routes.clear()使用vehicle.vehicleboundarymap_set.delete()。您将只会失去反向关系(RouteBoundary.vehicles),但您可以使用相同的方式实现它。

由于中间模型,其余的M2M field功能无论如何都是disabled