Как отфильтровать модель поля "многие ко многим"?
Я пытаюсь реализовать геозону для парка грузовиков. Я должен связать список границ с транспортным средством. Кроме того, одно из требований-сохранить все, даже если оно удалено для целей аудита. Поэтому мы должны реализовать soft delete на всем. Вот в чем проблема. Поле "многие ко многим" не соответствует менеджеру мягкого удаления, оно включает как активные, так и неактивные записи в наборе данных поиска.
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 ответов
первая проблема: использование limit_choices_to
не будет работать, так как информация:
limit_choices_to
не имеет никакого эффекта при использованииManyToManyField
С пользовательской промежуточной таблицей, указанной с помощью наVehicleBoundaryMap
, а неobjects
поэтому он игнорируется.единственный способ, который я вижу, который может работать быть:
создать прокси-модель на
VehicleBoundaryMap
. Назовем этоVehicleBoundaryMapProxy
. Установите его так, чтобы его менеджер по умолчанию -SoftDeleteManager()
что-то типа:class VehicleBoundaryMapProxy(VehicleBoundaryMap): class Meta: proxy = True objects = SoftDeleteManager()
есть
through='VehicleBounddaryMapProxy'
наManyToManyField
:class Vehicle(SoftDeleteModel): routes = models.ManyToManyField('RouteBoundary', through='VehicleBoundaryMapProxy', verbose_name=_('routes'))
что, если вы просто сделаете:
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
функции отключен в любом случае из-за промежуточной модели.