Using:
class PostSerializer(serializers.ModelSerializer):
author = ExtUserSerializer(required=False, allow_null=True)
class Meta:
model = Post
field = ('title','description','rating','author')
def create(self, validated_data):
return Post.objects.create(**validated_data)
and
#api_view(['GET'])
def post_list(request, format=None):
if request.method == 'GET':
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True)
return Response(serializer.data)
How to modify Serializer and view to fill field author automatically
Related
In Model.py
class Item(models.Model):
item_id = models.AutoField(primary_key=True)
item_description = models.CharField(max_length=500)
quantity = models.IntegerField(default=0)
avg_rate = models.IntegerField(default=0)
category_id = models.ForeignKey(category, on_delete=models.CASCADE)
last_purchase_rate = models.IntegerField(default=0)
added_date = models.DateTimeField(auto_now=True)
custom_id = models.CharField(max_length=11, unique=True, blank=True)
def save(self, *args, **kwargs):
self.custom_id = f"ITM-{str(self.item_id).zfill(5)}"
super().save(*args, **kwargs)
In Serializer.py
class ItemSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = '__all__'
def create(self, validated_data):
item = Item.objects.create(**validated_data)
item.custom_id = f"ITM-{str(item.item_id).zfill(5)}"
item.save()
return item
In view.py
#api_view(['GET', 'POST'])
def ItemsViewSet(request, format=None):
# GET.
if request.method == 'GET':
itemsdata = Item.objects.all()
serializer = ItemsSerializer(itemsdata, many=True)
return Response(serializer.data)
# POST.
if request.method == 'POST':
serializer = ItemsSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
SELECTED ITEM GET, PUT(UPDATE) & DELETE.
#api_view(['GET', 'PUT', 'DELETE'])
def items_detail(request, id):
# ID PICK POINT.
try:
itms = Item.objects.get(pk=id)
except itms.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
GET.
if request.method == 'GET':
serializer = ItemsSerializer(itms)
return Response(serializer.data)
# PUT.
elif request.method == 'PUT':
serializer = ItemsSerializer(itms, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# DELETE.
` elif request.method == 'DELETE':
itms.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
I want to set the Custom_ID in the format of 'ITM-00001', but currently, I am getting a Custom_ID of 'ITM-00None'. Additionally, this code also performs CRUD operations. I need the category_name to be displayed on the frontend instead of the category_ID.
NOTE: Using Python and Django rest framework current version. Database: MySQL
After user-registration, user wants to post data into Client model ( OnetoOne relationship with User model ). So, I want to access the requested user object inside the serializer-class to create a new row in Client model associated with the requested user.
models.py
class Client(models.Model):
user= models.OneToOneField(User, on_delete=models.CASCADE, null=False, blank=False)
sex = models.CharField(max_length = 6, blank=False, null=False)
location = models.CharField(max_length = 30, null = False, blank = False)
views.py
class ClientRegister(GenericAPIView):
def post(self, request):
user = request.user
serializer = ClientSerializer(data= request.data)
if serializer.is_valid():
serializer.save()
return Response(status= status.HTTP_201_CREATED)
else:
return Response(data= 'Invalid Form', status= status.HTTP_400_BAD_REQUEST)
serializers.py
class ClientSerializer(serializers.ModelSerializer):
class Meta:
model = Client
fields = ['sex', 'location']
def create(self, validated_data):
sex = validated_data.get('sex')
location = validated_data.get('location')
user = #------ Want requested user object here ------#
if user.is_client:
client = Client(user=user, sex=sex, location=location)
client.save()
return client
I have manually added user oject into the data in serializer = CientSerializer(data=request.data).
But, It didn't work. Please, tell me how to pass it from views.py or how to access it in serializers.py.
Pass user when you do serializer.save in post method of views like
def post(self, request):
u = request.user
serializer = ClientSerializer(data= request.data)
if serializer.is_valid():
serializer.save(user=u)
return Response(status= status.HTTP_201_CREATED)
else:
return Response(data= 'Invalid Form', status= status.HTTP_400_BAD_REQUEST)
Or you can read about passing context from views to serializers and in this context you can pass your required data like -
serializer = ClientSerializer(context = {'request':request}, data=request.data)
then you can have your request object in your serializers and you can get request.user or directly pass it in the context.
Try to pass the user with sex and location in views
class ClientRegister(GenericAPIView):
def post(self, request):
data = request.data
user = request.user
#add user in key
data['user']=user
serializer = ClientSerializer(data=data)
if serializer.is_valid():
serializer.save()
return Response(status= status.HTTP_201_CREATED)
else:
return Response(data= 'Invalid Form', status= status.HTTP_400_BAD_REQUEST)
serializer:
class ClientSerializer(serializers.ModelSerializer):
class Meta:
model = Client
fields = '__all__'
views.py
class ClientRegister(GenericAPIView):
def post(self, request):
user = request.user
serializer = ClientSerializer(context={'user':user}, data= request.data)
if serializer.is_valid():
serializer.save()
return Response(status= status.HTTP_201_CREATED)
else:
return Response(data= 'Invalid Form', status= status.HTTP_400_BAD_REQUEST)
serializers.py
class ClientSerializer(serializers.ModelSerializer):
class Meta:
model = Client
fields = ['sex', 'location']
def create(self, validated_data):
sex = validated_data.get('sex')
location = validated_data.get('location')
user = self.context.get('user')
if user.is_client:
client = Client(user=user, sex=sex, location=location)
client.save()
return client
I have Post model:
class Post(models.Model):
title = models.CharField(max_length=50)
text = models.CharField(max_length=1000)
published_date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
And a view:
#api_view(['GET', 'POST'])
def posts(request):
if request.method == 'GET':
post_list = Post.objects.all()
serializer = PostSerializer(post_list, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = PostSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors)
And serializer:
class PostSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(read_only=True)
author = UserSerializer(read_only=True)
category = CategorySerializer(read_only=True)
author_id = serializers.IntegerField(write_only=True)
category_id = serializers.IntegerField(write_only=True)
class Meta:
model = Post
fields = ('id', 'title', 'text', 'published_date', 'author', 'category', 'category_id', 'author_id')
I want to send POST request like {"title":"some title", "text":"some text", "category_id"=1}, so that author_id will be automatically current user id. How can I do this?
In the view, pass the current user to serializer.save() during the POST.
def posts(request):
if request.method == 'GET':
post_list = Post.objects.all()
serializer = PostSerializer(post_list, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = PostSerializer(data=request.data)
if serializer.is_valid():
serializer.save(author=request.user)
^^^
return Response(serializer.data)
return Response(serializer.errors)
I'm trying to make a rest API for a blog app using Django-rest-framework. I'm a beginner and it's hard for me to understand how to implement that system. I made an intermediary model for making connections between followers and followings and serializers for users. But my API showing absolutely wrong following and followers for each user and endpoints for following and unfollowing not working also. https://github.com/romon267/blog_api - my code
Models.py:
class UserFollowing(models.Model):
class Meta:
constraints= [
models.UniqueConstraint(fields=['user_id', 'following_user_id'], name='unique_following')
]
ordering = ['-created']
user_id = models.ForeignKey('auth.User', related_name='following', on_delete=models.SET_NULL, null=True,blank=True)
following_user_id = models.ForeignKey('auth.User', related_name='followers', on_delete=models.SET_NULL, null=True,blank=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'{self.user_id} is following {self.following_user_id}'
serializers.py:
class UserSerializer(serializers.HyperlinkedModelSerializer):
following = serializers.HyperlinkedRelatedField(many=True, view_name='user-detail', read_only=True)
followers = serializers.HyperlinkedRelatedField(many=True, view_name='user-detail', read_only=True)
posts = serializers.HyperlinkedRelatedField(many=True, view_name='post-detail', read_only=True)
class Meta:
model = User
fields = ['url', 'id', 'username', 'posts', 'following', 'followers']
def get_following(self, obj):
return FollowingSerializer(obj.following.all(), many=True).data
def get_followers(self, obj):
return FollowersSerializer(obj.followers.all(), many=True).data
class UserFollowingSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = UserFollowing
fields = '__all__'
class FollowingSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = UserFollowing
fields = ['id', 'following_user_id', 'created']
class FollowersSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = UserFollowing
fields = ['id', 'user_id', 'created']
views.py:
class UserViewSet(viewsets.ReadOnlyModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserFollowingViewSet(viewsets.ModelViewSet):
queryset = UserFollowing.objects.all()
serializer_class = UserFollowingSerializer
class UserFollow(APIView):
"""
Retrieve, update or delete a snippet instance.
"""
def get_object(self, pk):
try:
return User.objects.get(pk=pk)
except User.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
user = self.get_object(pk)
serializer = UserSerializer(user)
return Response(serializer.data)
def post(self, request, pk, format=None):
user = request.user
follow = self.get_object(pk)
UserFollowing.objects.create(user_id=user.id, following_user_id = follow.id)
serializer = UserSerializer(follow)
return Response(serializer.data)
def delete(self, request, pk, format=None):
user = request.user
follow = self.get_object(pk)
UserFollowing.objects.delete(user_id=user.id, following_user_id = follow.id)
serializer = UserSerializer(follow)
return Response(serializer.data)
I have created an api where one can upload pic for profile along with rest of the details. My problem is that if one wants to change the pic, how can it be done.
At present, I am able to save pic for the first time.
models.py
class Profile(models.Model):
User = get_user_model()
branch = models.CharField(max_length=20, null=True)
year = models.IntegerField(null=True)
image = models.ImageField(upload_to="accounts/images/", null=True, blank=True)
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
primary_key=False,
null=True
)
views.py
class ProfileView(APIView):
permission_classes = (IsAuthenticated,)
serializer_class = ProfileSerializer
queryset = Profile.objects.all()
def post(self, request, format=None):
current_user = request.user
param = request.data
profile = Profile.objects.filter(user=current_user.pk)
if profile:
serializer = ProfileSerializer(profile, many=True)
return Response(serializer.data)
else:
serializer = ProfileSerializer(data=param)
if serializer.is_valid(raise_exception=True):
serializer.save(user=current_user)
new_data = serializer.data
return Response(new_data)
return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)
class ProfileView(APIView):
permission_classes = (IsAuthenticated,)
def post(self, request, format=None):
try:
# exist then update
profile = Profile.objects.get(user=request.user)
serializer = ProfileSerializer(profile, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)
except Profile.DoesNotExist:
# not exist then create
serializer = ProfileSerializer(data=param)
if serializer.is_valid():
serializer.save(user=request.user)
return Response(serializer.data)
else:
return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)
or just use UpdateAPIView:
class ProfileView(UpdateAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = ProfileSerializer
queryset = Profile.objects.all()