Reputation: 5452
I have a Django model with a GenericForeignKey
, and several other models pointing to it through 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')
And I have a Django Rest Framework viewset that attempts to get all related records from the 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)
The problem is that the view raises the following exception:
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
I can see that the GenericRelation
is not being recognized. how can I execute the query I want, using generic relationships?
Upvotes: 0
Views: 140
Reputation: 727
inventory_action
is a field on your InventoryStockInit and InventoryInput models - you can't expect it to be a field in your InventoryAction model.
With the relation you defined, each of your InventoryAction objects can be related to a single object in one of he models stated in limit_choices_to
. There is only one object related to a single InventoryAction. You can access it by accessing action object
, for example:
inventory_action = InventoryAction.objects.first()
inventory_action.action_object # this will be a single object of one of the models in limit_choices_to.
Your InventoryInput
model on the other hand can be pointed by multiple inventory actions. To see which inventory actions are pointing to a particular InventoryInput object, you can do:
inventory_input = InventoryInput.objects.first()
inventory_input.inventory_action.all()
As you can see, inventory_action
is a manager of all related objects, it would be better to call it inventory_actions
(plural). I think what you might be trying to achieve is a reverse relation (single InventoryAction object referenced by multiple objects of other models).
Upvotes: 0