How to Patch an User Model of Django with Django RF? - python

I have UserProfile model that contains phone, profile_photo and some fields of Django default User model like first_name, last_name, email and I am trying to update some of these fields.
models.py
class UserProfile(models.Model):
user = models.ForeignKey(User, verbose_name="User")
phone = models.CharField(max_length=16, verbose_name="Phone")
profile_photo = models.ImageField(null=True, blank=True, upload_to=user_directory_path, verbose_name="Profile Photo")
serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('url', 'first_name', 'last_name', 'email')
class UserProfileSerializer(serializers.ModelSerializer):
user = UserSerializer(partial=True)
class Meta:
model = UserProfile
fields = '__all__'
def create(self, validated_data):
user_profile = UserProfile.objects.create(**validated_data)
return user_profile
views.py
class UserProfileViewSet(viewsets.ModelViewSet):
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
authentication_classes = (TokenAuthentication,)
#detail_route(methods=['PATCH'], url_path='update-partial')
def user_profile_update_partial(self, request, pk=None):
profile = UserProfile.objects.get(id=pk)
serializer = self.get_serializer(profile, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
If I send profile_photo, phone, first_name or last_name data with this #detail_route I am only able to update phone and profile_photo fields. Also getting Bad Request error when profile_photo data not sending.
How can I implement the partial_update with PATCH method?

class UserProfileViewSet(viewsets.ModelViewSet):
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
authentication_classes = (TokenAuthentication,)
def partial_update(self, request, *args, **kwargs):
profile = self.get_object()
serializer = self.get_serializer(profile, data=request.data, partial=True)
if serializer.is_valid():
user_serializer = UserSerializer(profile.user, data=request.data, partial=True)
if user_serializer.is_valid():
user_serializer.save()
serializer.save()
return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
else:
return Response(data=user_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else:
return Response(data=serializer.errors,status=status.HTTP_400_BAD_REQUEST)
Q1:How to implement PATCH method?
A1:Override partial_update method.
Q2:How to update first_name or last_name?
A2:Update it with another Serializer named UserSerializer.(If you want update password,you need use make_password method to create encoded password before save raw password to database)

Related

returning a non serializer field otp in django

I am trying to return otp to my response alongwith other serializer data. but as it is not submitted through request i am unable to understand how to give it in response. OTP is getting stored with other data in the user table perfectly but I am facing problem only in returning it in response .my code is given below:
models.py
class User(AbstractUser):
phone_number = models.IntegerField(null=True)
otp = models.IntegerField(null=True)
serializers.py
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
password_confirmation = serializers.CharField(read_only=True)
class Meta:
model = User
fields = ('username', 'password', 'password_confirmation', 'email', 'first_name', 'last_name', 'phone_number')
def create(self, validated_data):
password = validated_data.pop('password', None)
instance = self.Meta.model(**validated_data)
if password is not None:
instance.set_password(password)
instance.save()
instance.otp = randint(1, 98787)
instance.save()
return instance
def otp(self):
instance = self.Meta.model()
return instance.otp
views.py
#api_view(['POST'])
def user_signup(request):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
content = {'user': serializer.data, 'otp': UserSerializer.otp()}
return Response(content, status=status.HTTP_201_CREATED)
Since serializer.save() return instance you can do following:
if serializer.is_valid():
instance = serializer.save()
content = {'user': serializer.data, 'otp': instance .otp}
So def otp(self) in UserSerializer is not required.

Can't create user through POST request in Django

I'm new in Django and DRF and I'm trying to create a new user through POST request. I send the username and password parameters but django doesn't identify the parameters inside the POST request.
My serializer:
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
def create(self, validated_data):
user=get_user_model().objects.create(
username = validated_data['username']
)
user.set_password(validated_data['password'])
user.save()
return user
class Meta:
model = get_user_model()
fields = ('username', 'password')
My view class:
class CreateUserView(CreateAPIView):
model = get_user_model()
permission_classes = (AllowAny,)
serializer_class = UserSerializer
I have tried to use serializers.ModelSerializer and serializer.Serializers but don't have success.
class UserSerializer(serializers.ModelSerializer):
def create(self, validated_data):
user = UserModel.objects.create_user(**validated_data)
return user
class Meta:
model = YOUR_MODEL
fields = ('username', 'password',)
class CreateUserView(CreateAPIView):
model = YOUR_MODEL.objects.all()
permission_classes = (AllowAny,)
serializer_class = UserSerializer
You can do View as this and check your errors.
view.py
class CreateUser(APIView):
permission_classes = (AllowAny,)
def post(self, request):
post_data = request.data
print post_data # See what is your post DATA
serializer = UserSerializer(data=post_data)
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(data={'user':serializer.data})
return Response(data={'user':serializer.errors})

In django, django rest framework : User matching query does not exist

I copied https://pypi.python.org/pypi/fh-drf-friendship/0.1.1 (Because i don't know how to apply fh-drf-friendship on my project.)
views.py
class FriendViewSet(NestedViewSetMixin, mixins.ListModelMixin, mixins.CreateModelMixin,
mixins.DestroyModelMixin, viewsets.GenericViewSet):
serializer_class = UserSerializer
def create(self, request, *args, **kwargs):
request.data['to_user'] = self.get_parents_query_dict()['user']
serializer = FriendSerializer(data=request.data)
if serializer.is_valid():
instance = serializer.save()
headers = self.get_success_headers(serializer.data)
serializer = FriendReadSerializer(instance)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def get_object(self):
to_user = User.objects.get(pk=self.get_parents_query_dict().get('user'))
from_user = User.objects.get(pk=self.kwargs.get('pk'))
return Friend.objects.get(to_user=to_user, from_user=from_user)
serializers.py
class UserSerializer(serializers.ModelSerializer):
related_postwriter = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
related_commentwriter = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = User
fields = ('id', 'username', 'email', 'related_postwriter', 'related_commentwriter')
class FriendSerializer(rest_framework_common.serializers.ModelSerializer):
user = serializers.PrimaryKeyRelatedField(source='from_user', queryset=User.objects.all())
class Meta:
model = Friend
exclude = ('url', 'from_user',)
def create(self, validated_data):
fr = FriendshipRequest.objects.get(from_user=validated_data['from_user'], to_user=validated_data['to_user'])
if fr and fr.accept():
return Friend.objects.get(from_user=validated_data['from_user'], to_user=validated_data['to_user'])
class FriendReadSerializer(rest_framework_common.serializers.ModelSerializer):
user = UserSerializer(source='from_user')
created_at = serializers.DateTimeField(source='created')
class Meta:
model = Friend
exclude = ('url', 'from_user', 'to_user', 'created',)
django version == 1.9.7
django rest framework version == 3.4.1
python3 == 3.5
On urls.py, there are router.register(r'friend', views.FriendViewSet, base_name='friend')
And when i go http://127.0.0.1:8000/friend/ on web browser,
DoesNotExist at /friend/
User matching query does not exist. comes.
How can i solve it?

Django RestFrame work to update the fied

My serializer fun is
class change_pwdform(serializers.ModelSerializer):
def update(self, instance, validated_data):
user.set_password(validated_data.get('new_password', new_password))
user.save()
return instance
old_password = serializers.CharField( style={'input_type': 'password'})
new_password = serializers.CharField( style={'input_type': 'password'})
class Meta:
fields = ( 'pty_email','old_password','new_password',)
model = registration
in my model i have only the filed called
password field in model
my view function to change password is,
class Change_Password(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
serializer_class = change_pwdform
def post(self, request, format=None):
email = request.data['pty_email']
pwd = request.data['old_password']
user = registration.objects.filter(pty_email=email, pty_password=pwd)
if user:
user = registration.objects.get(pty_email=email)
request['password'] = request.data['new_password']
print request.data //says quickdict of email , password , new_password, and old_password
serializer = change_pwdform(object, data=request.DATA, partial=True)
if serializer.is_valid():
serializer.save()
data = { "result":"success"}
return Response(data)
error ={"Invalid"}
return Response(error, status=status.HTTP_400_BAD_REQUEST)
This request return a dict ack: success but the password is not yet changed.
Thanks in advance..
You can wright an update function in your serializers like this.Following
def update(self, instance, validated_data):
user.set_password(validated_data.get('new_password', new_password))
user.save()
return instance
Here user is the user object and in your views.py you have to pass the model object like this
change_pwdform = change_pwdform(object, data=request.DATA, partial=True)
This worked for me and you can also refer "http://www.django-rest-framework.org/api-guide/serializers/#customizing-multiple-update"

'dict' object has no attribute 'save' POST doesn't work

I'm building a REST web service, the GET method seems to be working all right
but when it comes to POST error message always shows up:
'dict' object has no attribute 'save'
models.py
from django.db import models
class Users(models.Model):
Fullname = models.CharField(max_length=50)
Username = models.CharField(max_length=15)
Password = models.CharField(max_length=8)
Email = models.CharField(max_length=50, unique=True)
Type = models.CharField(max_length=5)
TwitterName = models.CharField(max_length=15, unique=True)
FacebookName = models.CharField(max_length=15, unique=True)
CreationDate = models.DateTimeField()
serializer.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = Users
fields = ('Fullname', 'Username', 'Email', 'Password', 'Type', 'TwitterName', 'FacebookName')
views.py
#api_view(['GET', 'POST'])
def users_list(request, format=None):
if request.method == 'GET':
users = Users.objects.all()
serializer = UserSerializer(users, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = UserSerializer(request.DATA, many=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.data, status=status.HTTP_400_BAD_REQUEST)
I'm using PyCharm and Django 1.7
If you want to save the POST data then you should pass the data to data keyword argument:
serializer = UserSerializer(data=request.DATA, many=True)
if serializer.is_valid():
...
Also I would suggest you to use Class based views with Mixins as that will make your code much cleaner and shorter:
from rest_framework import generics, mixins
class UserList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = Users.objects.all()
serializer_class = UserSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)

Categories

Resources