I am trying to implement the best way for creating a serializer which I can user for CRUD

I have 4 different types of model and I want to create a serializer for one model where I can do the CRUD for all of them at once.

My Models:

class PropertyType(models.Model):


class Category(models.Model):


class Property(models.Model):
    property_type = models.ForeignKey(PropertyType, on_delete=models.CASCADE, verbose_name="Property Type")
    category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name="Property Category")

class Images(models.Model):
    property = models.ForeignKey(Property, on_delete=models.CASCADE)

Serializes:

from django.db.models import fields
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer, Serializer
from . models import Category, Images, Property, PropertyType

class CategorySerializer(ModelSerializer):

    class Meta:
        model = Category
        fields = "__all__"


class PropertyTypeSerializer(ModelSerializer):

    class Meta:
        model = PropertyType
        fields = "__all__"



class ImageSerializer(ModelSerializer):

    class Meta:
        model = Images
        fields = ["id", "url"]



class GetPropertySerializer(ModelSerializer):
    
    property_img = ImageSerializer(many=True)
    property_type = PropertyTypeSerializer()
    category = CategorySerializer()

    class Meta:
        model = Property
        fields = [
            "id", 
            "name",
            "rent_cost",
            "primary_cost",
            "bedrooms",
            "kitchen",
            "bathroom",
            "property_size",
            "furnished",
            "description",
            "localtion",
            "category", 
            "property_img",
            "landmark",
            "latitude",
            "longitude",
            "is_featured",
            "on_sale",
            "sold",
            "property_age",
            "property_type",
            "category",
            "created_at",
            "updated_at"
            ]


class CreatePropertySerializer(ModelSerializer):
    
    property_img = ImageSerializer(many=True)
    property_type = serializers.PrimaryKeyRelatedField(
        read_only=False, queryset=PropertyType.objects.all())
    category = serializers.PrimaryKeyRelatedField(
        read_only=False, queryset=Category.objects.all())

    class Meta:
        model = Property
        fields = [
            "id", 
            "name",
            "rent_cost",
            "primary_cost",
            "bedrooms",
            "kitchen",
            "bathroom",
            "property_size",
            "property_img",
            "furnished",
            "description",
            "localtion",
            "category", 
            "landmark",
            "latitude",
            "longitude",
            "is_featured",
            "on_sale",
            "sold",
            "property_age",
            "property_type",
            "category",
            "created_at"
            
            ]
    
    def create(self, validated_data):
        images = validated_data.pop('property_img')

        property = Property.objects.create(**validated_data)

        for img in images:
            Images.objects.create(**img, property=property)

        return property

Here is the github url Github repo url

Currently I can create all of them at once with property model but the serializer returns only foreignkey fields id after creating an instance.

I have searched on Google but couldn’t find a better result where I can do all of them from one serializer.

Please help me it will be life saving for me, I have been stuck with this approach for the past few weeks.

Hi @manascode, it sounds like your create view uses the CreatePropertySerializer on both the request and response side of things. You could potentially use a different serializer for the response side of things, but this can be difficult when using something like a GenericViewSet.

Instead, I would modify your CreatePropertySerializer to have read-only fields for the related serializers similar to what GetPropertySerializer has. For example:

class CreatePropertySerializer(ModelSerializer):
    
    property_type_id = serializers.PrimaryKeyRelatedField(
        read_only=False, queryset=PropertyType.objects.all())
    property_type = PropertyTypeSerializer(read_only=True)

Now when you make a post, you specify the property_type_id field and the response will contain a property_type field with the PropertyType serialized object in it.

Let me know if you need me to further clarify any parts of that. It’s a pretty short explanation.

1 Like

It means it will return two fields
one is only property type id
another one the property type model object
Yes, that could solve the issue, but I have been looking for using a single serialzer for all types of operation and also get the result with nested serialzers fields as well in all types of operation(crud).

And are you suggesting to user ViewSets or APIView to make those api views rather using generics api views?

@KenWhitesell any suggestions or solutions? The last time you saved my life.

Are you hoping to make changes to the nested fields as well in this single API endpoint? If so, then I apologize, I misunderstood. What I provided would not work in that case.

And are you suggesting to user ViewSets or APIView to make those api views rather using generics api views?

I wasn’t trying to suggest anything. I was attempting to describe what assumptions I had made to come up with my suggestion.

@CodenameTim Yup now got my point.

I’d love to help, but DRF is an area I’m only superficially familiar with. You’re well outside anything I have experienced.
I’ll glance through the docs to see if anything jumps out at me, but I’m not even 100% sure I really understand the issue and I’d hate to pepper you with questions if it’s not going to do you any good.