Home > OS >  How to add the entry, which has foreign key, from frontend having only the pk of fk
How to add the entry, which has foreign key, from frontend having only the pk of fk

Time:07-01

Probably not the best heading, but I will try my best to explain the question.

I have two models set up in my Django app:

class Category(models.Model):
    class Meta:
        verbose_name_plural = "Categories"

    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('home')



class Post(models.Model):
    title = models.CharField(max_length=255)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    body = models.TextField()
    post_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title   " | "   str(self.author)

    def get_absolute_url(self):
        return reverse('post-details', args=(str(self.id)))

with respective serializers:

class UserSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'first_name', 'last_name']


class CategorySerializer(ModelSerializer):
    class Meta:
        model = Category
        fields = ['id', 'name']


class PostSerializer(ModelSerializer):
    category = CategorySerializer()
    author = UserSerializer()

    class Meta:
        model = Post
        fields = ['id', 'title', 'author', 'category', 'body', 'post_date']

and a default ViewSet for Post:

from rest_framework.viewsets import ModelViewSet


class PostViewSet(ModelViewSet):
    serializer_class = PostSerializer
    queryset = Post.objects.all().order_by('-post_date')

I want to add a new entry by sending an axios POST request to my Django app from the Vue frontend and I would like to do it in such way:

      const formData =  {
        title: this.title,
        category: this.category,
        body: this.body,
        author: this.$store.state.user_id,
      }
      axios({
        method: "POST",
        url: '/api/blog/posts/',
        headers: {"Content-Type": "application/json"},
        data: formData
      })
      .then(response => {
        this.$router.push({ name: 'home' });
      })
      .catch(err=> {
        console.log(err.response.data)
      })

However, this obviously returns a Bad Request error, because I am passing the IDs of the author and category, and not the dictionaries with respective fields.

bad request

My question is: is it possible to pass only IDs in my request and create new entries based on them, or should I somehow get the user and category first, and return them in my POST request after?

CodePudding user response:

I think you need to set the additional fields for uploading author id and the category id.

class PostSerializer(ModelSerializer):
    category_id = serializers.IntegerField(write_only = True)
    author_id = serializers.IntegerField(write_only = True)
    category = CategorySerializer(read_only = True)
    author = UserSerializer(read_only = True)

    class Meta:
        model = Post
        fields = ['id', 'title', 'author', 'category', 'body', 'post_date', 'author_id', 'category_id']

And in the frontend, you need to upload integer ids.

const formData =  {
  title: this.title,
  category_id: parseInt(this.category, 10),
  body: this.body,
  author_id: parseInt(this.$store.state.user_id, 10),
}
  • Related