UNIQUE constraint failed on Posting form - python

I am trying to post a simle form to create a user. but whenever i try to save the form data it always gives me UNIQUE constraint failed error even if i pass the new mobile number that does not exist on database.
ERROR IS: UNIQUE constraint failed: core_user.mobile_no
models.py
Manager Class is:
class UserManager(BaseUserManager):
def create_user(self, username, password=None, **extra_fields):
"""Creates and saves a new user"""
if not password:
raise ValueError("User must have a password")
if not username:
raise ValueError("User must have an username")
user = self.model(username=username, **extra_fields)
user.set_password(password)
user.save(using=self.db)
return user
def create_staff_user(self, username, password=None, **kwargs):
user = self.create_user(username, password, is_staff=True, **kwargs)
return user
def create_super_user(self, username, password=None):
user = self.create_user(self, username=username, password=password, is_staff=True, is_super_user=True)
return user
Model class is:
class User(AbstractBaseUser):
user_types = (
("staff", "Staff"),
("super_user", "Super User"),
)
first_name = models.CharField(max_length=100)
middle_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
username = models.CharField(max_length=100, unique=True)
email = models.EmailField()
mobile_no = models.CharField(max_length=10, unique=True)
is_active = models.BooleanField(default=True) # can login
is_staff = models.BooleanField(default=False) # staff user
is_super_user = models.BooleanField(default=False) # super user
created_date = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'username'
objects = UserManager()
# USERNAME_FIELD and password are required by default
REQUIRED_FIELDS = [] # e.g full_name
def __str__(self):
return self.username
Views.py
class UserCreationView(CreateView):
template_name = "form.html"
form_class = UserCreationForm
success_url = "/"
def form_valid(self, form):
username = form.cleaned_data['username']
password = form.cleaned_data['password']
first_name = form.cleaned_data['first_name']
middle_name = form.cleaned_data['middle_name']
last_name = form.cleaned_data['last_name']
mobile_no = form.cleaned_data['mobile_no']
email = form.cleaned_data['email']
user_type = form.cleaned_data['user_type']
user_data = {
"first_name": first_name,
"middle_name": middle_name,
"last_name": last_name,
"mobile_no": mobile_no,
"email": email
}
if user_type == 'super-user':
user = User.objects.create_super_user(username, password, **user_data)
else:
user = User.objects.create_staff_user(username, password, **user_data)
form.instance.user = user
form.instance.is_active = True
form.save()
return super().form_valid(form)
Questions are:-
As far as i tried to debug, it could be the reason that create_staff_user and create_super_user functions have already created a row in database and now form.save() is also trying to insert the row again. (not sure)
do i need to do form.save() as i found that super().form_valid(form) also have implemented form saving function within it ?

In your view, you should only call save once, but you are calling it twice
form.save() # this line saves it to the database
super().form_valid(form) # and this line does that too
so after calling form.save() return response.
update, your code to
class UserCreationView(CreateView):
template_name = "form.html"
form_class = UserCreationForm
success_url = "/"
def form_valid(self, form):
username = form.cleaned_data['username']
password = form.cleaned_data['password']
first_name = form.cleaned_data['first_name']
middle_name = form.cleaned_data['middle_name']
last_name = form.cleaned_data['last_name']
mobile_no = form.cleaned_data['mobile_no']
email = form.cleaned_data['email']
user_type = form.cleaned_data['user_type']
user_data = {
"first_name": first_name,
"middle_name": middle_name,
"last_name": last_name,
"mobile_no": mobile_no,
"email": email
}
if user_type == 'super-user':
user = User.objects.create_super_user(username, password, **user_data)
else:
user = User.objects.create_staff_user(username, password, **user_data)
form.instance.user = user
form.instance.is_active = True
form.save()
return HttpResponseRedirect(self.get_success_url())
mobile number should be unique for every user
class UserForm(forms.ModelForm):
class Meta:
model = User
exclude = ('is_staff', 'is_superuser',)
def clean_mobile_no(self):
mobile_number = self.cleaned_data.get('mobile_no')
user = User.objects.filter(mobile_no=mobile_number)
if user:
raise forms.ValidationError(
"mobile no is taken"
)
return mobile_number

Well, as for your first question, it could be the problem. I guess before you created a custom User model, you makes migrations and pushed them to your database. So, that is the part where Django also creates its own User model, with all the available columns and attributes. I would suggest to DELETE your currently Users table, and run the makemigrations and migrate again.
As for your second question, the best practice and advice that I could give you is to first add an if clause, to check if the form data are valid, and then save the form and post the data. Although my advice does not really relate to your question, the point is to always validate the form's data and after you retrieve them, save the form (post the data).
In the documentation it says that the FormView class on success will redirect the user and on error, it will redisplay the form. However, the CreateView will only display the errors and save the object, it will not redirect to anything. Although with the CreateView you can automatically save the form and its data, it will not redirect the user. I suggest you using the FormView class that will show if there any errors and will redirect the user on success, but be careful and save the form data at the end of the POST function.
I hope that helps! Please let me know if there is anything else I can help you with.

Related

Django and DRF Why isn't my password hashing

I am using DRF and I have these pieces of code as models, register view and serializer
But anytime I signup a user the password does not hashed and I can't see to figure out why.
models.py
class UserManager(BaseUserManager):
def create_user(self, email, password=None, **kwargs):
if not email:
raise ValueError("Users must have an email")
email = self.normalize_email(email).lower()
user = self.model(email=email, **kwargs)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
if not password:
raise ValueError("Password is required")
user = self.create_user(email, password)
user.is_superuser = True
user.is_staff = True
user.save()
return user
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=255, unique=True)
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
role = models.CharField(max_length=255)
department = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
is_verified = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = UserManager()
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["first_name", "last_name", "role", "department"]
def __str__(self):
return self.email
serializers.py
class RegisterSerializer(serializers.ModelSerializer):
email = serializers.CharField(max_length=255)
password = serializers.CharField(min_length=8, write_only=True)
first_name = serializers.CharField(max_length=255)
last_name = serializers.CharField(max_length=255)
role = serializers.CharField(max_length=255)
department = serializers.CharField(max_length=255)
class Meta:
model = User
fields = ["email", "password", "first_name", "last_name", "role", "department"]
def create(self, validated_data):
return User.objects.create(**validated_data)
def validate_email(self, value):
if User.objects.filter(email=value).exists():
raise serializers.ValidationError("This email already exists!")
return value
views.py
class RegisterView(APIView):
serializer_class = RegisterSerializer
def post(self, request, *args):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
user_data = serializer.data
user = User.objects.get(email=user_data.get("email"))
return Response(user_data, status=status.HTTP_201_CREATED)
for some reason, which I don't know anytime a user is created the password is save in clear text. It does not hash the passwords. The superuser's password is however hashed because I created it with the command line but the api doesn't hash the password. I some help to fix this.
Instead of passing plain password you should use make_password method provided by django.
from django.contrib.auth.hashers import make_password
make_password(password, salt=None, hasher='default')
Creates a hashed password in the format used by this application. It takes one mandatory argument: the password in plain-text (string or bytes). Optionally, you can provide a salt and a hashing algorithm to use, if you don’t want to use the defaults (first entry of PASSWORD_HASHERS setting). See Included hashers for the algorithm name of each hasher. If the password argument is None, an unusable password is returned (one that will never be accepted by check_password()).
You can try something like this
hashed_pass = make_password(your_password_here, salt=None, hasher='default')
user = self.create_user(email, hashed_pass)
Source: https://docs.djangoproject.com/en/4.1/topics/auth/passwords/
Try this:
def create(self, validated_data):
password = validated_data.pop('password')
user = User.objects.create(**validated_data)
user.set_password(password)
user.save()
return user
I found why it wasn't working. In the create method in the RegisterSerializer I did a return User.objects.create(**validated_data)
which saves on the request data in the database, including the password without hashing it first. The correct way is to be calling the create_user method instead, like so return User.objects.create_user(**validated_data) since that method has the set_password mechanism to hash the password.

I want to assign value of logged in user's user_company to the user_company field of the newly created user

When a user creates a user record for a client, the new client should should have the current logged in user's User.user_company value.
In the problem here, I want to assign the value of the logged in user's User.user_company into the new user's clientuser.user_company when save() is called in the view.
here is the serializer below with the clientuser object.
class ClientSerializers(serializers.ModelSerializer):
password2 = serializers.CharField(style={'input_type': 'password'}, write_only=True)
client_name = serializers.CharField(style={'input_type' : 'text'}, required=True)
class Meta:
model = User
fields = ['email', 'username', 'password', 'password2', 'user_type', 'client_name']
extra_kwargs = {
'password': {'write_only': True}, #dont want anyone to see the password
'user_type': {'read_only': True},
}
def save(self):
clientuser = User(
#creating a user record. it will record company fk
email=self.validated_data['email'],
username=self.validated_data['username'],
user_type = 3,
first_name = self.validated_data['client_name'])
#validating the password
password = self.validated_data['password']
password2 = self.validated_data['password2']
if password != password2: #trying to match passwords.
raise serializers.ValidationError({'password': 'Passwords must match.'})
clientuser.set_password(password) #setting the password
clientuser.save() #saving the user
return clientuser
I've tried using
cur_usr = User()
param = 'user_company'
usr_comp = getattr(u, param)
print(f'usr_comp is {usr_comp})
print statement prints usr_comp is None in the terminal
I've also tried using
curr_User_Company = User.user_company
user.user_company = curr_User_Company
it returns the following line in the terminal
raise ValueError(
ValueError: Cannot assign "<django.db.models.fields.related_descriptors.ForwardManyToOneDescriptor object at 0x04B05F28>": "User.user_company" must be a "Company" instance.
Here is my user model
class User(AbstractUser):
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
user_type_data = ((1,"sysAdmin"),(2,"CompanyAdmin"), (3,"Client"), (4,"Employee"))
user_type = models.IntegerField(choices=user_type_data, default=2)
user_company = models.ForeignKey('Company', on_delete=models.CASCADE, null=True, blank=True)
#if user is CompAdmin then company is the company he belongs to
#if user is Client then company is the company he is serviced by
#if user is Employee then company is the company he works for
#if user is sysAdmin then company is null
Here is my view
#csrf_exempt
#permission_classes([IsAuthenticated])
def ClientApi(request):
if request.method == 'POST':
data = JSONParser().parse(request)
serializer = ClientSerializers(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
I'm not sure if this is necessary, but if it is, here is a sample of the data i tried to pass through Postman
{
"email":"Maximillian#amgracing.com",
"username":"Maximillian",
"password":"AmgRacingBetterThanRedBull",
"password2":"AmgRacingBetterThanRedBull",
"client_name" : "MaximillianRacing"
}
Maybe you should used this:
from django.contrib.auth import get_user
and this:
clientuser = User(
#creating a user record. it will record company fk
email=self.validated_data['email'],
username=self.validated_data['username'],
///
user_company = get_user(self.request).user_company /// this line get you user_company from logged user
Finally figured it out. I added current_user parameter to the save() function and assigned the user_company to the value of current_user.user_company
def save(self, current_user):
usr_comp = current_user.user_company
clientUser = User(///
user_company = usr_comp)
In the ClientApi view, here's what I did
serializer.save(current_user = request.user)

Django: NOT NULL constraint failed: wishlist_wish.user_id

I have a wishlist app with a custom user model. I added the user as the foreign key to each wishlist item. However, I am only able to add the foreign key by specifying a default user, even after deleting the existing db files and running makemigrations and migrate. The default user is associated with the wishlist item regardless of which user is logged in, and if I don't include a default user I get the "NOT NULL constraint failed: wishlist_wish.user_id" error.
How can I update the code so that the wishlist item is associated with the logged-in user creating the item?
A related question is whether I need to include a user id in my custom user model? I tried doing this as well and ran into the same problem. Thanks in advance.
Wish Model:
class Wish(models.Model):
name = models.TextField()
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
def __str__(self):
return self.name
Wish View:
def add_wish(request):
user = request.user
wishes = Wish.objects.filter(user=request.user)
if request.method == 'POST':
form = WishForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
form = WishForm()
context = {'form' : form, 'wishes' : wishes}
return render(request, 'wishlist/add_wish.html', context)
Wish Form:
class WishForm(ModelForm):
class Meta:
model = Wish
fields = ('name', )
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['name'].widget.attrs.update({'class' : 'textarea', 'placeholder' : 'Enter wishlist item'})
Custom User (Account) Model:
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, first_name, last_name, password=None):
if not email:
raise ValueError("Users must provide an email to create an account.")
if not first_name:
raise ValueError("Users must provide full name to create an account.")
if not last_name:
raise ValueError("Users must provide full name to create an account.")
user = self.model(
email = self.normalize_email(email),
username = username,
first_name = first_name,
last_name = last_name,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, first_name, last_name, password):
user = self.create_user(
email = self.normalize_email(email),
username = username,
first_name = first_name,
last_name = last_name,
password = password
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
email = models.EmailField(max_length=100, unique=True)
username = models.CharField(max_length=100, unique=False, blank=True, null=True)
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name']
objects = MyAccountManager()
def __str__(self):
return self.first_name + " " + self.last_name
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
You simply need to provide a value for the .user for the Wish you are creating:
from django.contrib.auth.decorators import login_required
#login_required
def add_wish(request):
wishes = Wish.objects.filter(user=request.user)
if request.method == 'POST':
form = WishForm(request.POST)
if form.is_valid():
form.instance.user = requst.user
form.save()
return redirect('home')
else:
form = WishForm()
context = {'form' : form, 'wishes' : wishes}
return render(request, 'wishlist/add_wish.html', context)
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].

RelatedObjectDoesNotExist at /register/ User has no profile for Extended User Model and Profile

When user registers the registration is done but a profile is not created and the error is thrown. In the database the user is created but without a profile. the error is highlighted at
"p_reg_form = ProfileRegisterForm(request.POST, instance=credentials.profile)"
The bellow are the .py files for the project.
This code use to work but has suddenly stopped.
models.py:
class User(AbstractBaseUser, PermissionsMixin):
"""
An abstract base class implementing a fully featured User model with
admin-compliant permissions.
Username and password are required. Other fields are optional.
"""
username_validator = UnicodeUsernameValidator()
username = models.CharField(
"username",
max_length=150,
unique=True,
help_text="Required. 150 characters or fewer. Letters, digits and #/./+/-/_ only.",
validators=[username_validator],
error_messages={"unique": "A user with that username already exists.", },
)
first_name = models.CharField("first name", max_length=30, blank=True)
last_name = models.CharField("last name", max_length=150, blank=True)
email = models.EmailField("email", blank=True, unique=True)
is_staff = models.BooleanField(
"staff status",
default=False,
help_text=["Designates whether the user can log into this admin site."],
)
is_active = models.BooleanField(
"active",
default=True,
help_text=(
"Designates whether this user should be treated as active. "
"Unselect this instead of deleting accounts."
),
)
date_joined = models.DateTimeField("date joined", default=timezone.now)
objects = UserManager()
EMAIL_FIELD = "email"
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ()
class Meta:
verbose_name = "user"
verbose_name_plural = "users"
def clean(self):
"""Try and find the new way to right this save"""
super(User, self).save()
self.email = self.__class__.objects.normalize_email(self.email)
def get_full_name(self):
"""
Return the first_name plus the last_name, with a space in between.
"""
full_name = "%s %s" % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
"""Return the short name for the user."""
return self.first_name
def email_user(self, subject, message, from_email=None, **kwargs):
"""Send an email to this user."""
send_mail(subject, message, from_email, [self.email], **kwargs)
class Profile(models.Model):
"""Profile class lists the library and choices and settings for each field in the model the Profile
and also sets the database structure"""
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
image = models.ImageField(default="default.jpg", upload_to="profile_pics")
date_birth = models.DateField(max_length=75, null=True, name="date_birth")
def __str__(self):
return str(self.user)
def get_absolute_url(self):
"""Definition for the absolute path to be rendered in the profile-detail view"""
# return f'{self.user.username} Profile'
return reverse("profile-detail", kwargs={"pk": self.pk})
class Profile1(models.Model):
"""This class lists the library classes and settings in the model"""
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
image = models.ImageField(default="default.jpg", upload_to="profile_pics")
def __str__(self):
return str(self.user)
def get_absolute_url(self):
"""Definition for the absolute path to be rendered in the profile-detail view"""
# return f'{self.user.username} Profile'
return reverse("profile-detail", kwargs={"pk": self.pk})
views.py:
def register(request):
"""This function provides the logic and condition for saving the classes, the form variables used
plus the message and the redirection or rendering url """
if request.method == "POST":
form = UserRegistrationForm(request.POST)
p_reg_form = ProfileRegisterForm(request.POST)
if form.is_valid() and p_reg_form.is_valid():
credentials = form.save()
credentials.user = request.user
p_reg_form = ProfileRegisterForm(request.POST, instance=credentials.profile)
p_reg_form.full_clean()
p_reg_form.save()
credentials.is_active = False
credentials.save()
current_site = get_current_site(request)
email_subject = "Activate Your Account"
message = render_to_string(
"users/activate_account.html",
{
"user": credentials,
"domain": current_site.domain,
"uid": urlsafe_base64_encode(force_bytes(credentials.pk)),
"token": account_activation_token.make_token(credentials),
},
)
to_email = form.cleaned_data.get("email")
email = EmailMessage(email_subject, message, to=[to_email])
email.send()
messages.success(
request,
f"Account successfully created for: {first_name} {last_name} , "
f"Please verify your email: {to_email} for access to your account",
)
# return HttpResponse('We have sent you an email,
# please confirm your email address to complete registration')
return TemplateResponse(
request, "users/register_email_sent_confirmation.html"
)
else:
form = UserRegistrationForm()
p_reg_form = ProfileRegisterForm()
context = {"form": form, "p_reg_form": p_reg_form}
return render(request, "users/register.html", context)
forms.py :
BIRTH_YEAR_CHOICES = [x for x in range(1909, 2021)]
class UserRegistrationForm(UserCreationForm):
"""This class lists the model and fields for the User model Registration Form"""
email = forms.EmailField()
first_name = forms.CharField()
last_name = forms.CharField()
class Meta:
"""The model called and the field/s to be filled by the form for rendering"""
model = User
fields = [
"first_name",
"last_name",
"email",
"username",
"password1",
"password2",
]
widgets = {"country": CountrySelectWidget()}
def clean_email(self):
"""This definition checks to see if any users already exist with this email."""
# Get the email
email = self.cleaned_data.get("email")
# Check to see if any users already exist with this email.
try:
match = User.objects.get(email=email)
except User.DoesNotExist:
# Unable to find a user, this is fine
return email
# A user was found with this as a username, raise an error.
raise forms.ValidationError(f"This email ({email}) address is already in use.")
class ProfileRegisterForm(forms.ModelForm):
"""This class lists the model and fields for the User model Profile Registration Form"""
date_birth = forms.DateField(
label="Date of birth",
initial=datetime.date.today,
widget=forms.SelectDateWidget(years=BIRTH_YEAR_CHOICES),
)
class Meta:
"""The model called and the field/s to be filled by the form for rendering"""
model = Profile
fields = ["date_birth",]
signals.py :
#receiver(post_save, sender=User)
def create_profile(instance, created):
"""This function lists the model to be created and saved for the classes relating to
other apps withing the project"""
if created:
Profile.objects.create(user=instance)
Profile1.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_profile(instance):
"""This function lists the model to be created and saved for the classes relating to
other apps withing the project"""
instance.profile.save()
instance.profile1.save()
settings.py :
AUTH_USER_MODEL = "users.User"
error :
RelatedObjectDoesNotExist at /register/
User has no profile.
Request Method: POST
Request URL: http://localhost:5000/register/
Django Version: 3.0.7
Exception Type: RelatedObjectDoesNotExist
Exception Value:
User has no profile.
The code worked previous and only started failing fairly recently, and advice would be grateful.
The problem is from
p_reg_form = ProfileRegisterForm(request.POST, instance=credentials.profile)
At this stage, your credentials do not have profile, therefore, the error.
Try to replace:
p_reg_form = ProfileRegisterForm(request.POST, instance=credentials.profile)
p_reg_form.full_clean()
p_reg_form.save()
with something like: you probably need to tweak a bit
profile = p_reg_form.save()
profile.user = request.user
p_reg_form.full_clean()
p_reg_form.save()
The DoesNotExist exception is raised when an object is not found for the given parameters of a query. Django provides a DoesNotExist exception as an attribute of each model class to identify the class of object that could not be found and to allow you to catch a particular model class with try / except .

How can I replace the forms with my serializer in django

Model.py
class UserProfileInfo(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE,default='')
# user = models.OneToOneField(User, on_delete=models.CASCADE)
phone_no = models.CharField(max_length=13,unique=True)
registered = models.BooleanField(default=False)
spam = models.BooleanField(default=False)
def __str__(self):
return self.user.username
Serializer.py
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField()
class Meta():
model = User
fields = ('username','email','password')
class UserProfileSerializer(serializers.ModelSerializer):
class Meta():
model = UserProfileInfo
fields = ('phone_no',)
views.py
def register(request):
registered = False
if request.method == 'POST':
user_serializer = UserSerializer(data=request.POST)
profile_serializer = UserProfileSerializer(data=request.POST)
if user_serializer.is_valid() and profile_serializer.is_valid():
user = user_serializer.save()
user.set_password(user.password) #saving hash value of password
user.save()
profile = profile_serializer.save(commit=False)
profile.user = user
profile.registered = True
profile.save()
registered = True
else:
print(user_serializer.errors)
else:
user_serializer = UserSerializer
profile_serializer = UserProfileSerializer
return Response(request,'basic_app/registration.html',{
'user_serializer':user_serializer,
'profile_form':profile_form,
'registered':registered
})
def user_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
print(username,password)
user = authenticate(username=username, password=password)
print(user)
if user:
if user.is_active:
login(request,user)
return render(request,'basic_app/search.html')
else:
return HttpResponse('Account not active!')
else:
# print(username,password)
return HttpResponse('Login credentials not correct!')
else:
return render(request,'basic_app/login.html')
Now I need to make changes to my views.py such that I can parallely populate the user and the profile model having one to one field. I was using the form which was working well but now I need to convert the code to rest API. Please help how I can keep the same functionality using the above serializer class. My aim is to register and login the user.
First, c method in the serializer like my simple code:
(I used to write this class in my REST project for register student)
class StudentRegistrationSerializer(serializers.ModelSerializer):
password = serializers.CharField(style={'input_type': 'password'}, required=True)
password2 = serializers.CharField(style={'input_type': 'password'}, required=True)
class Meta:
model = Student
fields = ['phone_number', 'password', 'password2', 'name', 'family']
extra_kwargs = {
'password': {'write_only': True}
}
def save(self, **kwargs):
phone_number = self.validated_data.get('phone_number')
name = self.validated_data.get('name')
family = self.validated_data.get('family')
password = self.validated_data.get('password')
password2 = self.validated_data.get('password2')
not_active = User.objects.filter(username=phone_number, is_active=False)
is_active = User.objects.filter(username=phone_number, is_active=True)
if password != password2:
raise serializers.ValidationError({'error': 'password not matched'})
if is_active:
raise serializers.ValidationError({'error': 'username already exist'})
if not_active:
raise serializers.ValidationError({'error': 'username already exist active your account'})
user = User(username=phone_number, password=password, is_active=False)
user.set_password(password)
user.save()
student = Student(phone_number=phone_number, user=user, name=name, family=family)
student.save()
return student
and return the saved object here is student
and I recommend you to use build-in LoginView in the third-party library like "rest_auth" this library handles Token
after installing "rest_auth" using :
pip install django-rest-auth
in the url file just import :
from rest_auth.views import LoginView
and use it without any complexity

Categories

Resources