Reputation: 791
I could not show reverse relation in Django Rest Framework. Here in my case, a rent can have multiple images and i want to display all the images of that rent(living room image, kitchen image, bathroom image etc) in /api/v1/rent, i mean in rent resource.
So, how do I fetch these Galleries to display in the Rental resource?
class Rental(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=300, blank=False, null=False)
phone_number = models.PositiveIntegerField(null=False, blank=False)
renter = models.CharField(choices=RENTER_CHOICES, max_length=1, default=RENTER_CHOICES[0])
def __str__(self):
return self.name
def user_directory_path(instance, filename):
return 'rent_{0}/{1}'.format(instance.rent.id, filename)
class Gallery(models.Model):
rent = models.ForeignKey(Rental, related_name="rent")
image = models.FileField(upload_to=user_directory_path)
tag = models.CharField(max_length=1, choices=TAGS, null=True, blank=True)
class GallerySerializer(serializers.ModelSerializer):
rent = serializers.ReadOnlyField()
class Meta:
model = Gallery
fields = ('rent', 'image', 'tag',)
class RentalSerializer(serializers.ModelSerializer):
user = serializers.ReadOnlyField(source='user.username')
# gallery = serializers.SerializerMethodField('get_children')
#
# def get_children(self, obj):
# print ('obj', obj.gallery_set)
# serializer = GallerySerializer(obj.gallery_set.all(), many=True)
# return serializer.data
gallery = GallerySerializer(source='gallery_set',many=True, read_only=True)
class Meta:
model = Rental
fields = ('user', 'name', 'phone_number','gallery',)
Right now i dont get the list of gallery, using both way, one commented way and another source='gallery_set' way.
UPDATE
if i do rent = GallerySerializer(many=True)
i get the list of galleries but does it make any sense?
[
{
"user": "admin",
"name": "Sunrise Home",
"phone_number": 9842333833,
"rent": [
{
"image": "http://localhost:8000/media/rent_1/sittingRoom.jpg",
"tag": "L"
}
]
}
]
in above api you see the galleries are shown but the name shows it as a list of rent inside rental resource. Can anyone help me to design an api better way?
Upvotes: 0
Views: 166
Reputation: 328
When you specify the foreign key relationship for Rental
in your Gallery
model the related_name
you specify automatically defines a field on the Rental
object. The name of that field is whatever you set related_name
to, in this case rent
.
The important thing to understand here is that the related_name
will be attached to the opposite side of the relationship from where the key is declared in your models. Because the related name is going to be a property of a Rental
object, a better name for it might be galleries
in your example.
Assuming you change the related_name
in your models from rental
to galleries
, you can define your Rental
serializer to output a list of associated galleries:
class RentalSerializer(serializers.ModelSerializer):
user = serializers.ReadOnlyField(source='user.username')
galleries = GallerySerializer(many=True, read_only=True)
class Meta:
model = Rental
fields = ('user', 'name', 'phone_number','galleries')
By declaring a GallerySerializer with the same name as the related_name
defined in your foreign key relationship, it will automatically find only galleries which are associated with the Rental being serialized.
In another example:
Let's say you have several Eggs in a Basket. We would want to create a many-to-one relationship between Eggs and a Basket and would accomplish this by creating a foreign-key relationship between the two. That would be in the form of storing the ID of the associated Basket
for each Egg
.
In Django, we would declare that foreign key on the Egg
model. This allows us to access the basket that an egg is in via egg.basket
. We also want to determine what eggs are in a particular basket. We do that by defining a related_name
on the foreign-key field. This tells Django what the field linking the basket to all its contained eggs should be called. Since this field refers to all eggs in a basket, we would call it eggs
.
In code:
class Basket(models.Model):
color = models.CharField()
class Egg(models.Model):
color = models.CharField()
basket = models.ForeignKey(Basket, related_name="eggs")
Upvotes: 1