Reputation: 81
Im having trouble with retrieving all fields I need from serializer. Scenario:
I have 2 tables: Item & Warehouse. Those tables are connected via M2M relationship via through table called InventoryStatus. What I need is to get Item info with nested warehouse info + status field from InventoryStatus Table. The problem is, I cant get the "status" field....
Model:
class InventoryItem(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
code = models.CharField(max_length=25, null=False, blank=True)
orgid = models.ForeignKey('glonass.Company', null=True, related_name='inventory_items_company')
title = models.CharField(max_length=150, null=False, blank=True)
inventory = models.ManyToManyField('CompanyBranch', through='InventoryStatus', related_name='branch_iventoryStatus')
class CompanyBranch(BaseDataDescTime, LocationInfo, PostInfo, PoboxInfo, ContactInfo):
id = models.UUIDField(primary_key=True, default=uuid.uuid4,
orgid = models.ForeignKey('glonass.Company', null=True, related_name='branches')
slug = models.SlugField(max_length=150, blank=True, null=False)
class InventoryStatus(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
inventoryitem = models.ForeignKey('InventoryItem', related_name='inventory_status_items', null=True)
orgid = models.ForeignKey('Company', null=True, related_name='inventory_status_company')
companybranch = models.ForeignKey('CompanyBranch', related_name='inventory_status_warehouses', null=True)
status = models.DecimalField(max_digits=9, decimal_places=2, null=True, blank=True, default=0)
Serializer:
class InventoryStatusSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = InventoryStatus
class CompanyBranchSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = CompanyBranch
class InventoryItemSerializer(serializers.HyperlinkedModelSerializer):
inventory = CompanyBranchSerializer(many=True)
class Meta:
model = InventoryItem
Output Needed:
[
{
'id': 'xxxxxxxxxxxxx',
'title': 'Car',
'inventory': [
{
'id': 'yyyyyyyyyyy',
'title': 'warehouse 1',
'status': 50
},
{
'id': 'zzzzzzzzzzzz',
'title': 'warehouse 2',
'status': 10
}
]
}
]
Upvotes: 3
Views: 637
Reputation: 1966
The problem is that M2M relations give directly the related object without any info on the "through" table, making it a pain when you want to serialize and grab some info in the "through" table. To solve this, I usually use the "through" relation to grab the information from the "through" table and the related items.
In your case it could look something like:
class InventoryStatusSerializer(serializers.ModelSerializer):
companybranch = CompanyBranchSerializer(many=True, read_only=True)
class Meta:
model = InventoryStatus
fields = ('status', 'companybranch')
class InventoryItemSerializer(serializers.ModelSerializer):
inventory = InventoryStatusSerializer(source='inventory_status_items', many=True, read_only=True)
class Meta:
model = InventoryItem
This would give output like (Note: I think you meant 'slug', not 'title' in the inventory items of your example):
[
{
'id': 'xxxxxxxxxxxxx',
'title': 'Car',
'inventory': [
{
'status': 50
'companybranch': {
'slug': 'warehouse 1',
'id': 'yyyyyyyyyyy', }
},
{
'status': 10
'companybranch': {
'slug': 'warehouse 2',
'id': 'zzzzzzzzzzzz',
}
}
]
}
]
Now if you want to flatten the output, just change the InventoryStatusSerializer
:
class InventoryStatusSerializer(serializers.ModelSerializer):
id = serializers.ReadOnlyField(source='companybranch.id')
slug = serializers.ReadOnlyField(source='companybranch.slug')
class Meta:
model = InventoryStatus
fields = ('status', 'id', 'slug')
Upvotes: 2
Reputation: 13
You need to add fields section to Serializers' Classes like following:
class CompanyBranchSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = CompanyBranch
fields = = ('id', 'orgid', 'slug')
you also need to do the same for the others.
Upvotes: 0