Reputation: 31
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)
Upvotes: 0
Views: 743
Reputation: 38
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()
...
Upvotes: 1