in model.py create a class in which 3 fields are there
class signUp(models.Model):
username = models.CharField(max_length=100)
email = models.EmailField()
password = models.IntegerField()
in serializer.py
class SignupSerializer(serializers.Serializer):
class Meta:
model = signUp
fields = ('username', 'email', 'password')
def create(self, validated_data):
email = validated_data['email'],
name = validated_data['name'],
password = validated_data['password']
return signUp.objects.create(**validated_data)
in views.py
#api_view(['POST'])
def signup(request):
if 'username' not in request.data:
response = {'message': 'please enter username'}
return Response(response, status=status.HTTP_400_BAD_REQUEST)
elif 'email' not in request.data:
response = {'message': 'please enter email'}
return Response(response, status=status.HTTP_400_BAD_REQUEST)
elif 'password' not in request.data:
response = {'message': 'please enter password'}
return Response(response, status=status.HTTP_400_BAD_REQUEST)
if request.method == 'GET':
signup = signUp.objects.all()
serializer = SignupSerializer(signup, many=True)
return JsonResponse(serializer.data, safe=False)
if request.method == 'POST':
data = JSONParser().parse(request)
serializer = SignupSerializer(data=data)
if serializer.is_valid():
user = serializer.validated_data.get('username')
message = f'successfully signup {user}'
return Response({message: message}, status=HTTP_200_OK)
All functions work and signup is a success, but after that data not show up in the database. How do I save it in the database?
Related
My Serializer.py
in this MovieSerializer I will check if "name" and "description" is same or not, if same then raise an error.
class MovieSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(max_length=80)
description = serializers.CharField(max_length=300)
def create(self, validated_data):
return Movie.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.name = validated_data.get('name', instance.name)
instance.description = validated_data.get('description', instance.description)
instance.save()
return instance
# object level validation
def validate(self, data):
if data['name'] == data['description']:
raise serializers.ValidationError("Name and Description can not be Same.")
else:
return data
My views.py
in serializer.is_valid() not pass raise_exception=True, when 'name' and 'description' is same it return a formated error message. output :
class MovieListAV(APIView):
def post(self, request):
serializer = MovieSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
My another serializer
validate "password" and "confirm_password" same or not, if different then raise an error.
class UserPasswordChangeSerializer(serializers.Serializer):
password = serializers.CharField(write_only=True, style={'input_type':'password'})
confirm_password = serializers.CharField(write_only=True, style={'input_type':'password'})
class Meta:
fields = ['password', 'confirm_password']
def validate(self, attrs):
password = attrs.get('password')
password2 = attrs.get('confirm_password')
if password != password2:
raise serializers.ValidationError({'password':'Password and Confirm Password Should be Same!'})
user = self.context.get('user')
user.set_password(password)
user.save()
return attrs
My other view
serializer.is_valid() not pass raise_exception=True, when "password" and "confirm_password" is dirrerent it can't return any formated error message.
but when I use "raise_exception=True" as a parameter of is_valid() like serializer.is_valid(raise_exception=True) then I got formated error message.
my question is, why this time I need to pass "raise_exception=True" ? but "MovieListAV" class view no need to pass "raise_exception=True" in is_view()
class UserPasswordChange(APIView):
authentication_classes = [JWTAuthentication, ]
permission_classes = [IsAuthenticated, ]
def post(self, request, *agrs, **kwargs):
user = User.objects.get(email=request.user)
serializer = UserPasswordChangeSerializer(data=request.data, context={'user':user})
if serializer.is_valid():
return Response({'success':'Password Change successfull.'}, status=status.HTTP_202_ACCEPTED)
return Response(serializer.errors, status=status.HTTP_304_NOT_MODIFIED)
I'm now making user profile update API using drf with RetreiveUpadteAPIView
there is one question that i can't figure out what the solution is.
This is what i want. I wanna update password and update other user data once for all.
changing password is worked as well as i supposed but other user datas (nick_name', 'wannabe', 'profile_img') are not save on DB through this logic below.
When i do self.object.set_password(), self.object.save() first and then do perform_update after. then user datas are well updated on DB. but password is saved without hashed even if i do set_password which is make the password hashed.
How can i fix it..
your best regard
Here is my code below.
#views.py
#permission_classes([IsAuthenticated])
class UpdatePartialUserView(RetrieveUpdateAPIView):
queryset = User.objects.all()
serializer_class = UserProfileSerializer
def get_object(self):
queryset = self.filter_queryset(self.get_queryset())
obj = queryset.get(pk=self.request.user.id)
self.check_object_permissions(self.request, obj)
return obj
def retrieve(self, request, *args, **kwargs):
serializer = UserSerializer(request.user)
return Response(status=status.HTTP_200_OK, data = serializer.data)
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
self.object = self.get_object()
serializer = self.get_serializer(request.user, data = request.data, partial=partial)
# serializer = self.get_serializer(self.object, data = request.data, partial=partial)
if not serializer.is_valid(raise_exception=True):
return Response(status=status.HTTP_409_CONFLICT, data = {'message':serializer.errors})
self.perform_update(serializer=serializer)
#make password hashed
self.object.set_password(request.data['password'])
self.object.save()
return Response(status=status.HTTP_202_ACCEPTED, data={"message": "success!"})
#serializers.py
class UserProfileSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True, required=True)
password2 = serializers.CharField(write_only=True, required=True)
old_password = serializers.CharField(write_only=True, required=True)
profile_img = serializers.ImageField(use_url=True, required = False)
def validate(self, attrs):
if attrs.get('password') != attrs.get('password2'):
raise serializers.ValidationError({
"password" : "passwords are not paired."})
return attrs
def validate_old_password(self, value):
#check user
request = self.context.get('request')
if request and hasattr(request, "user"):
user = request.user
if not user.check_password(value):
raise serializers.ValidationError({
"old_password" : "Old password is not correct."
})
return value
class Meta:
model = User
fields = ['nick_name', 'wannabe', 'old_password', 'password', 'password2', 'profile_img']
I think something like that should work.
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
self.object = self.get_object()
serializer = self.get_serializer(request.user, data = request.data, partial=partial)
if not serializer.is_valid(raise_exception=True):
return Response(status=status.HTTP_409_CONFLICT, data = {'message':serializer.errors})
self.object.set_password(new_password)
self.object.update(
nick_name=serializer.data["nickname"],
wannabe=serializer.data["wannabe"],
profile_img=serializer.data["profile_img"],
)
self.object.save()
return Response(status=status.HTTP_202_ACCEPTED, data={"message": "success!"})
User = get_user_model()
class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','phone' , 'password',)
write_only_fields = ('password',)
def create(self, validated_data):
user = User.objects.create(validated_data['phone'])
user.set_password(validated_data['password'])
user.save()
return user
})
class Register(APIView):
def post(self, request, *args, **kwargs):
phone = request.data.get('phone', False)
password = request.data.get('password', False)
print(phone)
print(password)
if phone and password:
old = PhoneOTP.objects.filter(phone__iexact=phone)
if old.exists():
old = old.first()
validated = old.validate
if validated:
temp_data = {
'phone': phone,
'password': password
}
serializers = CreateUserSerializer(data=temp_data)
serializers.is_valid(raise_exception=True)
user = serializers.save()
old.delete()
return Response({
'status': True,
'detail': 'Account is created '
})
while saving user pasword feild is shows Invalid password format or unknown hashing algorithm.
user is created the password feild is Invalid password format or unknown hashing algorithm.
uable to find y
also tried user.set_unusable_password() in serializer but same result could not figure it out
I try a lot a method you are using. It didn't save the password in the right form.
I suggest you create another model such as Profile and serializers for it and then try this -:
views.py
class Register(APIView):
permission_classes = (AllowAny, )
serializer_class = UserRegistrationSerializer
def post(self, request, *args, **kwargs):
phone = request.data.get('phone' , False)
if phone:
old = PhoneOTP.objects.filter(phone__iexact = phone)
if old.exists():
old = old.last()
validated = old.validated
if validated:
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
response = {
'success' : 'True',
'status code' : status.HTTP_200_OK,
'message': 'User registered successfully',
}
status_code = status.HTTP_200_OK
return Response(response, status=status_code)
else:
return Response({
'status' : False,
'detail' : "OTP haven't verified. FIrst do that step."
})
else:
return Response({
'status' : False,
'detail' : 'Please verify phone number first.'
})
else:
return Response({
'status' : False,
'detail' : 'Phone password, address, Date_Of_Birth, are not sent.'
})
serializers.py
class UserRegistrationSerializer(serializers.ModelSerializer):
profile = ProfileSerializer(required=False)
class Meta:
model = User
fields = ('phone', 'username', 'password', 'profile')
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = User.objects.create_user(**validated_data)
users = Profile.objects.create(
user=user,
state=profile_data['state'],
city=profile_data['city'],
date_Of_Birth=profile_data['date_Of_Birth'],
address=profile_data['address']
)
users.save()
return users
Hope the answer is useful
I have a registration page that allows a user to sign up. After doing so, I want to call an API and then, save the data to my model (not saving it to a form though). I tried doing this:
models.py:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE, primary_key=True, related_name = 'profile')
address = models.TextField()
birthday = models.DateField()
def __str__(self):
return str(self.user)
views.py:
def signup(request):
if request.method == 'POST':
user_form = UserForm(request.POST)
register_form = RegisterForm(request.POST)
if user_form.is_valid() and register_form.is_valid():
username = user_form.cleaned_data.get('username'),
first_name = user_form.cleaned_data.get('first_name'),
last_name=user_form.cleaned_data.get('last_name'),
email=user_form.cleaned_data.get('email'),
password=user_form.cleaned_data.get('password2'),
birthday = register_form.cleaned_data.get('dob'),
address=register_form.cleaned_data.get('address'),
payload = {'username': username,'first_name': first_name,'last_name': last_name,'email':email,'password':password,'register' : {'birthday': birthday,'address': address}}
response = requests.post('http://127.0.0.1:8000/my_api/',json=payload)
return redirect("home") #re-direct if login is successful
else:
user_form = UserForm()
register_form = RegisterForm()
return render(request, 'users/register.html', {'user_form': user_form, 'register_form': register_form})
class RegisterAPI(APIView):
permission_classes = [AllowAny]
def post(self, request, format=None):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
content = {'status': 'You are registered'}
return Response(content, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
serializers.py:
from users.models import Profile
from django.contrib.auth.models import User
class ProfileSerializer(serializers.ModelSerializer):
birthday = serializers.DateField(format="%Y-%m-%d")
class Meta:
model = Profile
fields = ('birthday','address')
class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = User
fields = ('username','first_name','last_name','email', 'password', 'profile')
def create(self, request, validated_data, *args, **kwargs):
register_data = validated_data.pop('profile')
password = validated_data.pop('password', None)
user = User.objects.create(**validated_data)
if password is not None:
user.set_password(password)
user.save()
Profile.objects.create(user = user, **register_data)
return validated_data
However, I am getting this error:
Object of type data is not JSON serializable error in Django
It seems that it's got to do with the birthday. On my template, a user can display the date of birth as 'YYYY-MM-DD'. How can I fix this error?
The create method in your UserSerializer should return a User instance instead of validated_data.
def create(self, request, validated_data, *args, **kwargs):
register_data = validated_data.pop('profile')
password = validated_data.pop('password', None)
user = User.objects.create(**validated_data)
if password is not None:
user.set_password(password)
user.save()
Profile.objects.create(user = user, **register_data)
return user
hello i learning about Django rest api, I am learning through someone else's code, but I don't know how to make Login.
my code :
model:
class User(models.Model):
class Meta:
db_table = "users"
created_at = models.DateTimeField(default = timezone.now)
updated_ay = models.DateTimeField(auto_now= True)
email = models.CharField(max_length = 128, unique= True)
password = models.CharField(max_length = 255)
active = models.BooleanField(default=False)
token = models.CharField(max_length= 255, null = True)
nickname = models.CharField(max_length = 255, null = True)
serializer:
class UserSerializer(serializers.ModelSerializer):
email = serializers.EmailField()
class Meta:
model = User
fields = '__all__'
def to_internal_value(self, data):
ret = super(UserSerializer, self).to_internal_value(data)
# cipher = AESSipher()
# ret['password'] = cipher.encrypt_str(ret['password'])
return ret
def to_representation(self, obj):
ret = super(UserSerializer, self).to_representation(obj)
print(ret)
return ret
def validate_email(self, value):
if User.objects.filter(email=value).exists():
raise serializers.ValidationError("Email already exists")
return value
def validate_password(self, value):
if len(value) < 8:
raise serializers.ValidationError("The password must be at least %s characters long. " % 8)
return value
def create(self, validate_data):
user = User.objects.create(
email = validate_data['email'],
password = validate_data['password'],
)
user.active = False
user.save()
message = render_to_string('user/account_activate_email.html', {
'user': user,
'domain' : 'localhost:8000',
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user)
})
mail_subject = 'sign up mail.'
to_email = 'mymail#gmail.com'
email = EmailMessage(mail_subject, message, to=[to_email])
email.send()
return validate_data
views:
class SignUp(APIView):
def post(self, request):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class UserActivate(APIView):
permission_classes = (permissions.AllowAny,)
def get(self, request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk = uid)
except(TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
try:
if user is not None and account_activation_token.check_token(user, token):
user.active = True
user.token = token
user.save()
return Response(user.email + 'email active', status=status.HTTP_200_OK)
else:
return Response('Expired Link', status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
print(traceback.format_exc())
Since I want to handle log-in status in the Mobile Client section,
I want to get only user model information when I log-in.
When Enter Email and Password in Client and I want to get user information.
How to make log-in? Do you know anyone?
Here is the link to the article: custom user authentication; it should help you
https://wsvincent.com/django-rest-framework-user-authentication-tutorial/
Hi you can use Django packages for this. for example you can use rest-auth package this package have all the things that you need for log in log out and reset password and all you need is that follow the rest auth documentation :
. https://pypi.org/project/django-rest-auth/
. https://django-rest-auth.readthedocs.io/en/latest/