softmarshmallow
softmarshmallow

Reputation: 1284

DRF oneToOneField Create Serializer

trying to do some nested model creation with drf/create serizlizer.

what i'm trying to serialize is 'TradePost' model, which has post, and ProductItem in it.

i already have 'ProductItemSerializer', and 'PostSerializer' by using this.. how can i serialize them?? with creation? not by telling existing record with pk value.

models.py

class ProductItem(models.Model):
    baseProduct = models.ForeignKey(Product, related_name='baseProduct')

    seller = models.ForeignKey(User)

    price = models.DecimalField(max_digits=6, decimal_places=2)

    isOrderClosed = models.BooleanField()
    isTradeCompleted = models.BooleanField()


    def __str__(self):
        return '[seller = '+self.seller.username+']' + '[product = '+(str)(self.baseProduct)+']' + '[id = '+(str)(self.id)+']'




class TradePost(models.Model):

    basePost = models.OneToOneField(Post)

    baseProductItem = models.OneToOneField(ProductItem)

    def __str__(self):
        return '[post = ' + (str)(self.basePost) + ']' + '[product = ' + (str)(self.baseProductItem) + ']' + '[id = ' + (str)(self.id) + ']'

in serialziers.py

class ProductItemCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductItem
        fields = ('baseProduct', 'price')



#???
class TradePostCreateSerializer(serializers.ModelSerializer):

    class Meta:
        model = TradePost
        fields = ('basePost', 'baseProductItem',)

    def create(self, validated_data):
        post =

Upvotes: 2

Views: 8062

Answers (2)

Nathan Do
Nathan Do

Reputation: 2035

Similar to the writable nested serializer, you can try something like this:

class TradePostCreateSerializer(serializers.ModelSerializer):
    basePost = PostCreateSerializer()
    baseProductItem = ProductItemCreateSerializer()

    class Meta:
        model = TradePost
        fields = ('basePost', 'baseProductItem',)

    def create(self, validated_data):
        # pop out the dict to create post and item, depend on whether you want to create post or not
        post = validated_data.get('basePost')
        product = validated_data.get('baseProductItem')
        # create post first
        trade_post = None
        post_obj = Post.objects.create(**post)
        if post_obj:
            # create product item
            prod_item = ProductItem.objects.create(basePost=post_obj, **product)
            trade_post = TradePost.objects.create(baseProduct=prod_item, **validated_data)
        return trade_post

For python, please follow naming convention and use lower_case_with_underscores like base_product, base_post, it will be much easier to read

Upvotes: 3

Sagar Ramachandrappa
Sagar Ramachandrappa

Reputation: 1461

You can use serializers to represent field, For eg,

class TradePostCreateSerializer(serializers.ModelSerializer):
    basePost = PostSerializer()
    baseProductItem = ProductItemSerializer()

    class Meta:
        model = TradePost
        fields = ('basePost', 'baseProductItem',)

Reference:

DRF Nested relationships

If you're looking for writable nested serializers

Writable nested serializers

Upvotes: -1

Related Questions