drf serializer data not showing all fields data properly - python

id field and name field not showing in result.
in models.py:
class Group(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
admin = models.ForeignKey(User, on_delete=models.CASCADE)
member = models.ManyToManyField(User, related_name='groups_user')
def __str__(self):
return self.name
in serializers.py:
class SimpleUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','first_name', 'last_name')
class GroupSerializer(serializers.Serializer):
admin = SimpleUserSerializer()
class Meta:
model = Group
fields = ('id','name','admin')
views.py:
#api_view(['GET'])
#permission_classes((IsAuthenticated,))
def getSomeGroup(request):
allGroup = Group.objects.all().count()
randomGroupId = random.sample(range(allGroup), 3)
randomGroup = Group.objects.filter(id__in=randomGroupId)
serializer = GroupSerializer(randomGroup, many=True)
#print(serializer)
return Response(serializer.data)
the result comes like this:
[{"admin":{"id":1,"first_name":"asif","last_name":""}},{"admin":{"id":3,"first_name":"Test2","last_name":"lastname"}},{"admin":{"id":3,"first_name":"Test2","last_name":"lastname"}}]
why id and name field not showing?

class SimpleUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
First try to access all admin
#api_view(['GET'])
#permission_classes(IsAuthenticated)
def getSomeGroup(request):
randomGroup = Group.objects.all()
serializer = GroupSerializer(randomGroup, many=True)
return Response(serializer.data)
If that works there may be issue in your these two line
The Issue may be in these two lines
allGroup = Group.objects.all().count()
randomGroupId = random.sample(range(allGroup), 3)

Modify serializers.py:
class GroupSerializer(serializers.ModelSerializer):

Related

How can I get the records (of a specific model) of both request.user and a specific user?

I am not very professional in django rest...
I wrote a blog with django rest framework and There is no problem when I want to get all the records related to the Article model or get a specific article, for example
But what I want to do is to send an user id(or an user name) to the view when I click on the user's name.
and as a result display all the records of the Article model related to the request.user and all the records of the Article model related to the user whose name was clicked.
In fact, I want to click on the name of each user, in addition to getting the Articles of that user, the Articles related to the request.user will also be taken
This is what I have done so far...
#models.py
class Article(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField
author = models.ForeignKey(User , on_delete = models.CASCADE)
content = models.TextField(null = True)
publish = models.DateTimeField(default = timezone.now)
created = models.DateTimeField(auto_now_add = True)
updated = models.DateTimeField(auto_now = True)
status = models.BooleanField(default = False)
def __str__(self):
return self.title
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
pic = models.ImageField(upload_to="img", blank=True, null=True)
def __str__(self):
return self.user.username
#views.py
class ArticleCreate(CreateAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
class ArticleList(ListAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
class ArticleDetail(RetrieveUpdateDestroyAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
class UserDetail(RetrieveUpdateDestroyAPIView):
queryset = get_user_model().objects.all()
serializer_class = UserSerializer
class UserProfile(RetrieveUpdateDestroyAPIView):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
#serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
fields = "__all__"
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = "__all__"
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
exclude = ['updated' , 'created']
You should directly make several modifications in get_queryset() method by using Q objects so:
class ArticleList(ListAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
def get_queryset(self):
user_id = self.kwargs.get('user_id')
if user_id:
articles = Article.objects.filter(Q(author_id=user_id) | Q(author=self.request.user))
return articles
return self.queryset
You'll also need to modify your urls.py file to include the user_id parameter in the URL so:
from django.urls import path
from .views import ArticleList
urlpatterns = [
path('articles/<int:user_id>/', ArticleList.as_view(), name='article_list'),
# ... Other routes.
]
example URL: http://example.com/api/purchases?username=denvercoder9
class ArticleList(ListAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
def get_queryset(self):
username = self.request.query_params.get('username')
if username:
return User.objects.filter(username=username).article_set.all()
user = self.request.user
return Article.objects.filter(author=user)

Filter nested serializer model field (exclude particular field)

I am new to Django and I am trying to exclude a model field in nested serializer.
modals.py
class Blog(models.Model):
title = models.CharField(max_length=30)
description = models.CharField(max_length=30)
class Comment(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name="comment")
comment_bdy = models.CharField(max_length=30)
completed = models.BooleanField(default=False)
serializers.py
class BlogCommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ("id", "comment_body")
class BlogSerializer(serializers.ModelSerializer):
comment = BlogCommentSerializer(many=True)
class Meta:
model = ("id", "title", "description", "comment",)
I am trying to exclude comment which have completed=True .
I have tried many times like :-
class BlogCommentSerializer(serializers.ModelSerializer):
def to_representation(self, data):
data = data.filter(completed=False)
return super(BlogCommentSerializer, self).to_representation(data)
But It showing:
AttributeError: 'CommentReply' object has no attribute 'filter'
Then I tried using:
class BlogSerializer(serializers.ModelSerializer):
def get_comment(self, instance):
comment_instance = instance.comment_set.exclude(completed=True)
return BlogSerializer(comment_instance , many=True).data
It also didn't work.
What I am trying to do
I am trying to exclude comments which are completed=True.
You can try like this using SerializerMethodField:
class BlogSerializer(serializers.ModelSerializer):
comment = serializers.SerializerMethodField()
def get_comment(self, instance):
comment_instances = instance.comment.exclude(completed=True)
return BlogCommentSerializer(comment_instances , many=True).data
Try it:
class BlogSerializer(serializers.ModelSerializer):
comment = serializers.SerializerMethodField()
def get_comment(self, obj):
queryset = Comment.objects.
filter(blog=obj).exclude(blog__completed=True)
return [BlogCommentSerializer(q).data for q in queryset]

queryset get data of the foreign key

I have 2 models ( Users and Posts )
class Users(models.Model):
email = models.CharField(max_length=225)
class Posts(models.Model):
user = models.ForeignKey(Users, on_delete=models.CASCADE, default=1)
type = models.TextField()
I want to include the user email when getting all posts.
I have done the following but am only getting the user id.
class PostsViewSet(viewsets.ModelViewSet):
serializer_class = PostsSerializer
def get_queryset(self):
queryset = Posts.objects.all()
return queryset
How can I achieve to get the user email within the queryset ?
use https://docs.djangoproject.com/en/4.1/ref/models/querysets/#prefetch-related (not strictly needed, but a good habit) to grab it from the database, use post.user.email to grab the value in code. i.e:
class PostsViewSet(viewsets.ModelViewSet):
serializer_class = PostsSerializer
queryset = Posts.objects.all().prefetch_related("user")
class PostsSerializer(serializers.ModelSerializer):
email = serializers.EmailField(source="user.email")
...
You can annotate the field in the queryset:
from django.db.models import F
class PostsViewSet(viewsets.ModelViewSet):
serializer_class = PostsSerializer
def get_queryset(self):
queryset = Posts.objects.annotate(user_email=F('user__email'))
return queryset
Use all power of serializers. https://www.django-rest-framework.org/api-guide/serializers/
class PostsViewSet(viewsets.ModelViewSet):
serializer_class = PostsSerializer
queryset = Posts.objects.all().prefetch_related("user")
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email')
class PostsSerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = Post
fields = ('type', 'user')
depth = 1

Rest Framework cant save serializer with foreign key

I have next serializers:
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'
class PostSerializer(serializers.ModelSerializer):
category = CategorySerializer()
class Meta:
model = Post
fields = ['id', 'title', 'text', 'date', 'category']
And here is my view:
#api_view(['POST'])
def create_post(request):
serializer = PostSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
else:
return Response(serializer.errors)
return Response(serializer.data)
I want to create new Post object, but when I pass an category id at form it does not work, it is not saving my object. I tried to replace create method at my PostSerializer, to this:
def create(self, validated_data):
category_id = validated_data.pop('category')
post = Post.objects.create(**validated_data, category=category_id)
return post
but this dont work. Using postman formdata it is saying, that category field is required despite I filled it.
Here is my models:
class Category(models.Model):
name = models.CharField(max_length=512)
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=512)
text = models.TextField()
date = models.DateTimeField(auto_now_add=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='category')
You need a category object not just an id, so try this
#api_view(['POST'])
def create_post(request):
category_id = request.data['category'] # or however you are sending the id
serializer = PostSerializer(data=request.data)
if serializer.is_valid():
category = Category.objects.get(id=category_id)
serializer.save(category=category)
else:
return Response(serializer.errors)
return Response(serializer.data)
or you can do something similar in the create method of the serializer

How to return the Comment list by WorkOrder?

I have such a case:
I have a WorkOrder class:
class WorkOrder(models.Model):
workorder_num = models.CharField(max_length=64, help_text="workorder number")
name = models.CharField(max_length=32, help_text="name")
content = models.TextField(help_text="content")
And I also have a WorkOrderComment class:
class WorkOrderComment(models.Model):
"""
comment
"""
workorder = models.ForeignKey(WorkOrder, help_text="belong to which order" )
comment_user = models.OneToOneField(User, help_text="comment user")
content = models.CharField(max_length=256, help_text="content")
So, there is a requirement, I want to list the workorder comments, so I write the serializers and views:
serializer:
class WorkOrderCommentSerializer(ModelSerializer):
class Meta:
model = WorkOrderComment
fields = "__all__"
view:
class WorkOrderCommentListAPIView(ListAPIView):
serializer_class = WorkOrderCommentSerializer
permission_classes = []
queryset = WorkOrderComment.objects.filter()
But if I list workorder comment, you know it will list all the comments, no organization.
I want to through workorder to get its comments how to do with that?
You can use the nested-relationships to do that.
You do not need the WorkOrderCommentListAPIView.
You can in your WorkOrderCommentSerializer:
class WorkOrderCommentSerializer(ModelSerializer):
comments = WorkOrderCommentSerializer(many=True, read_only=True)
class Meta:
model = WorkOrderComment
fields = "__all__"
Then the access WorkOrderCommentSerializer you can get what you want.

Categories

Resources