获取Django模型的所有相关通用记录

时间:2020-10-28 02:53:00

标签: python django django-models django-rest-framework

我有一个带有GenericForeignKey的Django模型,还有其他几个通过GenericRelation指向它的模型:

class InventoryAction(CustomModel):
    action_content_type = models.ForeignKey(ContentType, on_delete=models.PROTECT,limit_choices_to={'model__in': ('inventoryinput', 'inventorytransfer', 'inventoryadjustment', 'physicalinventory', 'requisition', 'sale', 'inventorysalecancellation', 'inventorystockinit')}, related_name='inventory_actions', verbose_name=_("Tipo de Acción"))
    action_object_id = models.PositiveIntegerField(verbose_name=_("ID de la acción"))
    action_object = GenericForeignKey('action_content_type', 'action_object_id')
    timestamp = models.DateTimeField(auto_now=True, verbose_name=_("Fecha y hora"))

class InventoryStockInit(CustomModel):
    repository = models.ForeignKey(Repository, on_delete=models.PROTECT, related_name='stock_init', verbose_name=_("Almacén"))
    timestamp = models.DateTimeField(auto_now=True, verbose_name=_("Fecha y Hora"))
    comments = models.TextField(null=True, blank=True, verbose_name=_("Comentarios"))
    inventory_action = GenericRelation(InventoryAction, content_type_field='action_content_type', object_id_field='action_object_id')

class InventoryInput(CustomModel):
    repository = models.ForeignKey(Repository, on_delete=models.PROTECT, related_name='inputs', verbose_name=_("Almacén"))
    reference = models.ForeignKey(InventoryAction, null=True, blank=True, on_delete=models.PROTECT, limit_choices_to=Q(action_content_type__model__in=['inventorytransfer', ]), related_name='referenced_by', verbose_name=_("Referencia"))
    inventory_action = GenericRelation(InventoryAction, content_type_field='action_content_type', object_id_field='action_object_id')

我有一个Django Rest Framework视图集,试图从GenericForeignKey获取所有相关记录:

class InventoryActionForListViewSet(viewsets.ViewSet):
    permission_classes = (permissions.IsAuthenticated,)
    
    def list(self, request):
        self.repository = request.query_params['repository']

        inventory_actions = models.InventoryAction.objects.filter(inventory_action__repository_id=self.repository).order_by('-timestamp')

        inventory_actions_to_return = serializers.InventoryActionForListSerializer(inventory_actions, many=True)

        return Response(inventory_actions_to_return)

问题是该视图引发以下异常:

django.core.exceptions.FieldError: Cannot resolve keyword 'inventory_action' into field. Choices are: action_content_type, action_content_type_id, action_object, action_object_id, batch, id, products, referenced_by, referenced_by_input_or_output, referenced_by_output, timestamp

我看到GenericRelation未被识别。如何使用通用关系执行所需的查询?

1 个答案:

答案 0 :(得分:0)

inventory_action是InventoryStockInit和InventoryInput模型上的一个字段-您不能期望它是InventoryAction模型中的一个字段。

使用您定义的关系,您的每个InventoryAction对象都可以与limit_choices_to中所述的一种模型中的单个对象相关。只有一个与单个InventoryAction相关的对象。您可以通过访问action object来访问它,例如:

inventory_action = InventoryAction.objects.first()
inventory_action.action_object  # this will be a single object of one of the models in limit_choices_to.

另一方面,您的InventoryInput模型可以由多个库存操作来指示。要查看哪些库存操作指向特定的InventoryInput对象,您可以执行以下操作:

inventory_input = InventoryInput.objects.first()
inventory_input.inventory_action.all()

如您所见,inventory_action是所有相关对象的管理者,最好将其称为inventory_actions(复数)。我认为您可能想实现的是反向关系(单个InventoryAction对象由其他模型的多个对象引用)。​​