0

I have two models, "Blog_model" and "File_model" where "blog_id" of "Blog_model" is the foreign key for "File_Model". The concept is to save multiple files for a single blog. Here is the model structure for reference.

class Blog_model(models.Model):
    type = models.CharField(max_length = 50, default = "FOOD")
    count = models.PositiveIntegerField(default = 0)
    title = models.CharField(max_length = 500, unique = True)
    substance = models.CharField(max_length = 5000, default = "")
    thumbnail = models.ImageField(upload_to = get_media_file_name, default = "")
    text = models.TextField()
    create_time = models.DateTimeField(auto_now_add = True)
    update_time = models.DateTimeField(auto_now = True)


class File_model(models.Model):
    blog_id = models.ForeignKey(Blog_model, on_delete = models.CASCADE)
    file_name = models.FileField(upload_to = get_media_file_name)
    upload_time = models.DateTimeField(auto_now_add = True)

    def __str__(self):
        return str(self.file_name)

Now, I want to create a new blog using a single API that will have details of blogs, as well as file names. I am imagining the API structure something like -

{
"type": "FOOD",
"title": "Some Blog",
"Substance": "Some blog about food",
"text": "This is some blog about food",
"thumbnail": <InMemoryUploadedFile: Capture.PNG (image/png)>
"files": [<InMemoryUploadedFile: food1.jpg (image/jpeg)>, <InMemoryUploadedFile: food2.jpg (image/jpeg)>, <InMemoryUploadedFile: food3.jpg (image/jpeg)>]
}

Please suggest how to achieve the goal.
You may suggest a correct API structure also if above mentioned seems to be wrong.
Any suggestion is appreciated.
This is the serializer and view I am using for this purpose.

-----------------------------------
serializers.py
-----------------------------------

class File_modelCreateSerializer(serializers.ModelSerializer):
    # upload_time = serializers.DateTimeField(format = date_time_format)

    class Meta:
        model = File_model
        fields = ["file_name"]


class Blog_modelCreateSerializer(serializers.ModelSerializer):
    files = File_modelCreateSerializer(many = True, required = False)

    class Meta:
        model = Blog_model
        fields = ["type", "title", "substance", "thumbnail", "text", "files"]

    def create(self, validated_data):
        # files = validated_data.pop("files")       # Getting no key named "files" in validated_data
        new_blog = Blog_model.objects.create(**validated_data)

        # for f in files:
        #     File_model.objects.create(blog_id = new_blog, **f)

        return new_blog


-----------------------------------
views.py
-----------------------------------

# class Blog_modelCreateView(generics.CreateAPIView):   
#     serializer_class = Blog_modelCreateSerializer

class Blog_modelCreateView(APIView):
    parser_classes = (MultiPartParser, FormParser)

    def post(self, request, *args, **kwargs):
        blog_serializer = Blog_modelCreateSerializer(data = request.data)
        if blog_serializer.is_valid():
            blog_serializer.save()
            return Response(blog_serializer.data)
        else:
            return Response(blog_serializer.errors)

1 Answer 1

1

Actually, View and Serializer are linked to a model. But, you can use @action decorator.

See Django REST Framework: Routing for extra actions

If you want to link File serializer to Blog, try this.

class BlogViewSet(ModelViewSet):
    def get_serializer(self):
        if self.action == 'files':
           return FileSerializer
    ...
    @action(url_path='files')
    def file(self):
        qs = File.objects.all()
        ...
Sign up to request clarification or add additional context in comments.

Comments

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.