8

I have three models Blogs, Posted, Tags. In Blogs model I have fields 'postedin' as foreign key to Posted model and 'tags' as manytomany fields to Tags model.

models.py:

class Posted(models.Model):
    name = models.CharField(_('Posted In'),max_length=255, unique=True)

class Tags(models.Model):
    name = models.CharField(_('Tag Name'),max_length=255, unique=True)

class Blogs(models.Model):
    author = models.ForeignKey(CustomUser)
    title=models.CharField(max_length=100)
    postedin=models.ForeignKey(Posted)
    tags= models.ManyToManyField(Tags)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

views.py:

class BlogViewSet(viewsets.ModelViewSet):
    queryset=Blogs.objects.order_by('-created_at')
    serializer_class= BlogsSerializer

def get_permissions(self):
    if self.request.method in permissions.SAFE_METHODS:
        return (permissions.AllowAny(),)
    return (permissions.IsAuthenticated(),IsAuthorOfBlog())

def perform_create(self,serializer):

    serializer.save(author=self.request.user)

    return super(BlogViewSet,self).perform_create(serializer)

serializers.py:

class TagsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tags

        fields = ('pk','name')
        read_only_fields=('pk','name')

class PostedSerializer(serializers.ModelSerializer):
    class Meta:
        model = Posted

        fields = ('pk','name')
        read_only_fields=('pk','name')

class BlogsSerializer(serializers.ModelSerializer):
    author = AccountSerializer(read_only=True,required=False)
    tags=TagsSerializer(read_only=True,many=True)
    tags_id = serializers.PrimaryKeyRelatedField(queryset=Tags.objects.all(), write_only=True)
    postedin = PostedSerializer(read_only=True)
    postedin_id = serializers.PrimaryKeyRelatedField(queryset=Posted.objects.all(), write_only=True)

    class Meta:
        model = Blogs

        fields = ('pk','author','title','tags','tags_id','postedin','postedin_id','content','created_at','updated_at')
        read_only_fields=('pk','created_at','updated_at')


    def get_validation_exclusions(self, *args, **kwargs):
        exclusions = super(BlogsSerializer, self).get_validation_exclusions()

        return exclusions + ['author']
    def create(self, validated_data):
        postedin = validated_data.pop('postedin_id')
        tags = validated_data.pop('tags_id')
        blogs = Blogs.objects.create(tags=tags,postedin=postedin, **validated_data)
        return blogs

Request sent:

{title: "nvnbv", postedin_id: "1", tags_id: ["2", "5", "1", "4"], content: "nmvmvjm"}

response receive:

{tags_id: ["Incorrect type. Expected pk value, received list."]}

I am beginner in Django-rest-framework.How to solve this error.

Thanks in advance !

5
  • 2
    Have you tried with serializers.PrimaryKeyRelatedField(queryset=Tags.objects.all(), write_only=True, many=True)? Commented Sep 9, 2016 at 6:44
  • @Abdulafaja getting error "'tags' is an invalid keyword argument for this function" Commented Sep 9, 2016 at 7:01
  • Which function? Give all error Commented Sep 9, 2016 at 7:05
  • @Abdulafaja. after applying your suggestion . In 'def create(self, validated_data)' function Commented Sep 9, 2016 at 7:18
  • docs.djangoproject.com/es/1.10/topics/db/examples/many_to_many you cannot associate ManyToMany field before the Blogs is created Commented Sep 9, 2016 at 7:35

2 Answers 2

18

thanks @Abdulafaja for your suggestion.

Finally I got solution

BlogsSerializer should be

class BlogsSerializer(serializers.ModelSerializer):
    author = AccountSerializer(read_only=True,required=False)
    tags=TagsSerializer(read_only=True,many=True)
    tags_id = serializers.PrimaryKeyRelatedField(queryset=Tags.objects.all(), write_only=True,many=True)
    postedin = PostedSerializer(read_only=True)
    postedin_id = serializers.PrimaryKeyRelatedField(queryset=Posted.objects.all(), write_only=True)

    class Meta:
        model = Blogs

        fields = ('pk','author','title','tags','tags_id','postedin','postedin_id','content','created_at','updated_at')
        read_only_fields=('pk','created_at','updated_at')


    def get_validation_exclusions(self, *args, **kwargs):
        exclusions = super(BlogsSerializer, self).get_validation_exclusions()

        return exclusions + ['author']
    def create(self, validated_data):
        postedin = validated_data.pop('postedin_id')
        tags = validated_data.pop('tags_id')
        blogs = Blogs.objects.create(postedin=postedin, **validated_data)
        for tg in tags:
            blogs.tags.add(tg)
        return blogs
Sign up to request clarification or add additional context in comments.

Comments

2

Instead of loop, you can simply use this line blogs.tags.add(*tags)

def create(self, validated_data):
    postedin = validated_data.pop('postedin_id')
    tags = validated_data.pop('tags_id')
    blogs = Blogs.objects.create(postedin=postedin, **validated_data)
    blogs.tags.add(*tags)
    return blogs

1 Comment

Even better, blogs.tags.set(tags) because is a CREATION not an UPDATE.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.