Hii I am new to django rest framework i am able to perform put delete and get operations but unable to perform post operations
models.py
class User(auth.models.User, auth.models.PermissionsMixin): def __str__(self): return "@{}".format(self.username) class User_log(models.Model): user = models.OneToOneField(auth.models.User,on_delete=models.CASCADE,related_name='user_logs') fullname=models.CharField(max_length=255) fb_login=models.BooleanField(default=False) def __str__(self): return self.fullname
serializers.py
class userSerializers(serializers.ModelSerializer): password1=serializers.CharField(source="user.password1",write_only=True) password2=serializers.CharField(source="user.password2",write_only=True) fullname=serializers.CharField(source='user_logs.fullname') fb=serializers.BooleanField(source='user_logs.fb_login') class Meta: model = User fields=('id','username','email','password1','password2','fullname','fb') related_fields = ['user_logs'] def update(self, instance, validated_data): # Handle related objects for related_obj_name in self.Meta.related_fields: data = validated_data.pop(related_obj_name) related_instance = getattr(instance, related_obj_name) # Same as default update implementation for attr_name, value in data.items(): setattr(related_instance, attr_name, value) related_instance.save() return super(userSerializers,self).update(instance, validated_data)
urls.py
from django.urls import path,include from django.contrib.auth import views as auth_views from . import views from rest_framework import routers router=routers.DefaultRouter() router.register('accounts',views.Userview,basename='user') app_name = 'accounts' urlpatterns = [ path('login/', auth_views.LoginView.as_view(template_name="accounts/login.html"),name='login'), path('logout/', auth_views.LogoutView.as_view(), name="logout"), path('signup/', views.SignUp.as_view(), name="signup"), path('password-reset/', auth_views.PasswordResetView.as_view( template_name='accounts/password_reset_email.html' ), name='password_reset'), path('password-reset/done/', auth_views.PasswordResetDoneView.as_view( template_name='accounts/password_reset_done.html' ), name='password_reset_done'), path('password-reset-confirm/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view( template_name='accounts/password_reset_confirm.html' ), name='password_reset_confirm'), path('password-reset-complete/', auth_views.PasswordResetCompleteView.as_view( template_name='accounts/password_reset_complete.html' ), name='password_reset_complete'), path('',include(router.urls)), ]
views.py
class Userview(viewsets.ModelViewSet): def get_serializer_class(self): return userSerializers def get_queryset(self): return User.objects.all() def list(self,request): queryset = User.objects.all() serializer=userSerializers(queryset,many=True) if serializer.is_valid: return Response(serializer.data)
this is the json format when i perform get request
[ { "id": 1, "username": "karm", "email": "karm@gmail.com", "fullname": "ss", "fb": false } ]
As mentioned earliew whenever i perform put delete or get its working but its not a case with post the error i get is this:
AssertionError at /accounts/accounts/
The .create()
method does not support writable dotted-source fields by default.
Write an explicit .create()
method for serializer accounts.serializers.userSerializers
, or set read_only=True
on dotted-source serializer fields.
Advertisement
Answer
Two points to consider here:
- DRF Serializers do not support
write_only
. Instead, useextra_kwargs
in the serializer’sMeta
block. - Write a
create
method in your serializer. Rough example below.
See this from the docs for more information about write-only fields in DRF serializers.
class userSerializers(serializers.ModelSerializer): password1=serializers.CharField(source="user.password1") password2=serializers.CharField(source="user.password2") fullname=serializers.CharField(source='user_logs.fullname') fb=serializers.BooleanField(source='user_logs.fb_login') class Meta: model = User fields fields=['id','username','email','password1','password2','fullname','fb'] related_fields = ['user_logs'] extra_kwargs = { 'password1': {'write_only': True}, 'password2': {'write_only': True}, } def create(self, validated_data): // adjust to fit your actual User model user = User( email=validated_data['email'], username=validated_data['username'] ) user.set_password(validated_data['password']) user.save() return user