I'm pretty sure there's a better way to do this:
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ('category', 'id', 'title', 'image', 'slug', 'author', 'excerpt', 'content', 'status', 'published')
class FrontendPostSerializer(serializers.ModelSerializer):
author = AuthorSerializer(many=False, read_only=True)
category = CategorySerializer(many=False, read_only=True)
class Meta:
model = Post
fields = ('category', 'id', 'title', 'image', 'slug', 'author', 'excerpt', 'content', 'status', 'published')
PostSerializer
is gonna look like this
{
"category": 1,
"id": 45,
"title": "Lorem Ipsum - Lorem ipsum dolor sit amet consectetur",
"image": "http://localhost:8000/media/posts/car_SxXcUTV.jpg",
"slug": "lorem-ipsum-lorem-ipsum-dolor-sit-amet-consectetur",
"author": 4,
"excerpt": "Officiis iure rerum voluptates a cumque velit \nquibusdam sed amet tempora. Sit laborum ab, eius fugit doloribus tenetur \nfugiat, temporibus enim commodi iusto libero magni deleniti quod quam \nconsequuntur! Commodi minima excepturi repudiandae velit hic maxime\ndoloremque.",
"content": "Officiis iure rerum voluptates a cumque velit \nquibusdam sed amet tempora. Sit laborum ab, eius fugit doloribus tenetur \nfugiat, temporibus enim commodi iusto libero magni deleniti quod quam \nconsequuntur! Commodi minima excepturi repudiandae velit hic maxime\ndoloremque.",
"status": "published",
"published": "2021-10-01T14:46:34.872576Z"
}
FrontendPostSerializer
is gonna look like this
{
"category": {
"name": "django"
},
"id": 45,
"title": "Lorem Ipsum - Lorem ipsum dolor sit amet consectetur",
"image": "http://localhost:8000/media/posts/car_SxXcUTV.jpg",
"slug": "lorem-ipsum-lorem-ipsum-dolor-sit-amet-consectetur",
"author": {
"username": "luigi.verdi"
},
"excerpt": "Officiis iure rerum voluptates a cumque velit \nquibusdam sed amet tempora. Sit laborum ab, eius fugit doloribus tenetur \nfugiat, temporibus enim commodi iusto libero magni deleniti quod quam \nconsequuntur! Commodi minima excepturi repudiandae velit hic maxime\ndoloremque.",
"content": "Officiis iure rerum voluptates a cumque velit \nquibusdam sed amet tempora. Sit laborum ab, eius fugit doloribus tenetur \nfugiat, temporibus enim commodi iusto libero magni deleniti quod quam \nconsequuntur! Commodi minima excepturi repudiandae velit hic maxime\ndoloremque.",
"status": "published",
"published": "2021-10-01T14:46:34.872576Z"
}
What I'm doing atm is using FrontendPostSerializer
for showing data in the frontend, for example in a table with category name, author name and title. Instead, I'm using PostSerializer
for the backend CRUD.
These are the viewsets I'm using in the views.py
class ManagePosts(viewsets.ModelViewSet):
serializer_class = PostSerializer
parser_classes = [MultiPartParser, FormParser]
def get_object(self, queryset=None, **kwargs):
item = self.kwargs.get('pk')
return get_object_or_404(Post, slug=item)
# Define Custom Queryset
def get_queryset(self):
return Post.objects.all()
class FrontendPosts(viewsets.ModelViewSet):
serializer_class = FrontendPostSerializer
def get_object(self, queryset=None, **kwargs):
item = self.kwargs.get('pk')
return get_object_or_404(Post, slug=item)
# Define Custom Queryset
def get_queryset(self):
return Post.objects.all()
I already tried to use only one serializer, I had this:
class PostSerializer(serializers.ModelSerializer):
author = AuthorSerializer(many=False, read_only=True)
category = CategorySerializer(many=False, read_only=True)
class Meta:
model = Post
fields = ('category', 'id', 'title', 'image', 'slug', 'author', 'excerpt', 'content', 'status', 'published')
but, for example, when I try to create a new post it doesn't work, because category and author are not numbers, but objects.
I'm also gonna put here create.js
I have in my React frontend that handles the create submit.
const handleSubmit = (e) => {
e.preventDefault();
let formData = new FormData();
formData.append('category', 1);
formData.append('title', postData.title);
formData.append('slug', postData.slug);
formData.append('author', userInfo.id);
formData.append('excerpt', postData.excerpt);
formData.append('content', postData.content);
if(postImage.image !== null) {
formData.append('image', postImage.image);
}
axiosInstance.post('', formData);
history.push({
pathname: '/admin/',
});
window.location.reload();
};
Is there a better way? I'm sure I can use only one serializer, but I'm not sure how yet.
Thanks!
CodePudding user response:
Is there any specific reason to use one serializer for you? It is common to use WriteSerializer and ReadSerializer for the same object.
CodePudding user response:
Actually yes. You can add specific fields you want by using the source attribute. Example:
class PostSerializer(serializers.ModelSerializer):
authorUserName = serializers.CharField(read_only=true, source="author.username")
categoryName = serializers.CharField(read_only=true, source="category.name"
class Meta:
model = Post
fields = (
'category', 'id', 'title',
'image', 'slug', 'author',
'excerpt', 'content', 'status',
'published', 'authorName', 'categoryName')
# Remember add the field that are created
And when you try to get you should get the result like this:
{
"categoryName": "django",
"category": 1,
"id": 45,
"title": "Lorem Ipsum - Lorem ipsum dolor sit amet consectetur",
"image": "http://localhost:8000/media/posts/car_SxXcUTV.jpg",
"slug": "lorem-ipsum-lorem-ipsum-dolor-sit-amet-consectetur",
"authorName": "luigi.verdi",
"author": 4,
"excerpt": "Officiis iure rerum voluptates a cumque velit \nquibusdam sed amet tempora. Sit laborum ab, eius fugit doloribus tenetur \nfugiat, temporibus enim commodi iusto libero magni deleniti quod quam \nconsequuntur! Commodi minima excepturi repudiandae velit hic maxime\ndoloremque.",
"content": "Officiis iure rerum voluptates a cumque velit \nquibusdam sed amet tempora. Sit laborum ab, eius fugit doloribus tenetur \nfugiat, temporibus enim commodi iusto libero magni deleniti quod quam \nconsequuntur! Commodi minima excepturi repudiandae velit hic maxime\ndoloremque.",
"status": "published",
"published": "2021-10-01T14:46:34.872576Z"
}