Django rest framework create password for custom user model - python

Actually I'm creating an employee management system project using django rest api.
Now i have created my own custom models like shown below, i want to create the register employee with the below models. But how can i set the password field for login, since I haven't included in my fields. I've attached my models and serializer. Please do help for me. I'm beginner
Class Employee (models.Model):
name = models.CharField(max_length=50, unique=True, verbose_name='None')
email = models.EmailField(verbose_name='Email')
department = models.CharField(max_length=30, unique=False, verbose_name='Departamento')
(And many more details like personal email,contact, and many)
# Function used to display the employee's name in the admin page
def __str__(self):
return self.name
My serializer class is
class Employee DetailsSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
Fields = [__all__]
My views be like, i want to create register view, since i dont have password in my model, how to create password field to my above shown register field,
Whatever maybe my register field should contain all those above details. I'm scratching my head here.please someone help

Yes, you can add a password field in your Employee model but you are requested not to do it because Django already provided this type of facility. Just you have to know How to use it. Try to extend the existing User model from django.contrib.auth.models.User.Let's organize your Employee model.
from django.contrib.auth.models import User
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
#name = models.CharField(max_length=50, unique=True,
verbose_name='None')
#email = models.EmailField(verbose_name='Email')
department = models.CharField(max_length=30, unique=False,
verbose_name='Departamento')
#property
def name(self):
return "{0} {1}".format(self.user.first_name,
self.user.last_name)
No need to add an email field because this field already exists in the User model and the name field can be a property that retrieves data from the user model and the rest of the code will be unchanged. So you are concerned about the password field and it also exists in the User model.
Please check out this repo and it might help you.

Related

It is impossible to add a non-nullable field Error when extending Abstract User

I want to extend the Base Abstract User Model and this is the extended model:
class Student(AbstractUser):
birth = models.DateField(default=datetime.date.today)
street = models.CharField(max_length=25)
street_number = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(99)])
city = models.CharField(max_length=20)
province = models.CharField(max_length=20)
code = models.IntegerField(validators=[MinValueValidator(0, MaxValueValidator(9999))])
address = str(street) + str(street_number) + str(city) + str(code) + str(province)
But I get this message popup:
It is impossible to add a non-nullable field 'password' to student without specifying a default. This is because the database needs something to populate existing rows.
However I haven't added a new password field and all the existing password fields (for the superuser) already have a value. What should I do?
When I add a default value and try to migrate it, it complains that there is no such table as 'mainApp_student'.
You don't want to do that. You want a User model (you already have one that Django provides, no need to extend it for now), and a Student model that has a OneToOne relationship with the User model.
Conceptually:
User: models a user of your application and its authentication and permissions
Student: the representation of a person attending classes, with a name, a birthday etc..., also has a user to access your application which is unique to them.
In code:
from django.db import models
from django.contrib.auth.models import User
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE))
# ... other fields: birth address etc...
This page of the docs explains it well, especially the Employee example given:
If you wish to store information related to User, you can use a OneToOneField to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user.

How to show username in django admin form for the connected model?

I have two models one is user model and another one is cars model.
class User(models.Model):
id = models.BigAutoField(primary_key=True)
username = models.CharField(max_length=50, verbose_name="User Name")
class Cars(models.Model):
id = models.BigAutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='cars')
Now on /admin/app/cars/1/change/ page i want to see the username as a normal text in that form below the dropdown of users.
I tried with inline stack but that didn't worked, and throwing error, User has to foreign key to Cars.
The text shown in the admin panel is determined by the __str__ function, so adding something like
def __str__(self):
return self.username
to your user model should be enough

Trying to extend AbstractUser to create multiple user types in Django

So I have been searching all around the internet for a full example of how to user AbstractUser when u have at least 2 different models. Didn't find anything conclusive.. at least that would work on latest version of Django (2.0.1).
I have 2 models, teacher and student, and registration needs to be different. Besides username, email, name and surname, I need for example, for the student, to upload a profile picture, email, phone, student_ID. And for teacher, bio, academic title and website. Did I start good ? What is the right approach ?
class Profile(AbstractUser):
photo = models.ImageField(upload_to='students_images')
email = models.EmailField()
phone = models.CharField(max_length=15, )
class Student(Profile):
student_ID = models.CharField(unique=True, max_length=14,
validators=[RegexValidator(regex='^.{14}$',
message='The ID needs to be 14 characters long.')])
def __str__(self):
return self.name
class Teacher(Profile):
academic_title = models.CharField(max_length=30)
bio = models.TextField()
website = models.URLField(help_text="E.g.: https://www.example.com", blank=True)
Your goals can be accomplished using a 'Profile' pattern. You don't necessarily need to use a custom user model for this. But you need to have a single common model to for authentication; you can use the builtin django user for this or a custom class... Your Student and Teacher models should be OnetoOne relationships. This is the recommended solution per the documentation.
If you wish to store information related to User, you can use a OneToOneField to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user.
In your case, you may do something like this:
class StudentProfile(models.Model):
user = models.OneToOneField('User', related_name='student_profile')
# additional fields for students
class TeacherProfile(models.Model):
user = models.OneToOneField('User', related_name='teacher_profile')
# additional fields for teachers
Then you can create your registration forms based on these profile models.
class StudentResistrationForm(forms.ModelForm):
class Meta:
model = StudentProfile
fields = (...)
class TeacherRegistrationForm(forms.ModelForm):
class Meta:
model = TeacherProfile
fields = (...)
You can create the user instance to which the profile is related to at the same time you create the profile. You might do this with formsets, for example.
add
class Meta:
abstract = True
to profile model
and change AbstractUser to models.Model

Multiple User Types In Django

I am new to Django and trying to create an App with two User Types (Freelancers and Customers). I understand how to create a User profile Class and it works well for me:
class UserProfile(models.Model):
user = models.OneToOneField(User)
description = models.CharField(max_length=100, default='')
country = models.CharField(max_length=100, default='')
website = models.URLField(default='')
phone = models.IntegerField(default=0)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
This works well for me on a one user type user. But now I am building an app with 2 types of users (freelancers and customers), what is the best approach to get this done. Both users will have different view and info. Should I:
Create 2 different apps, and repeat the normal registeration and login for each.
If I do the above, hope the freelancers when logged in won't access customers view.
How do I add user type to the user profile if I decide to use one app and model for it.
Please I need a step by step beginner approach, or a link to relevant source.
Thanks.
You could try this:
class UserProfile(models.Model):
user = models.ForeignKey(User)
#define general fields
class Freelancer(models.Model):
profile = models.ForeignKey(UserProfile)
#freelancer specific fields
class Meta:
db_table = 'freelancer'
class Customers(models.Model):
profile = models.ForeignKey(UserProfile)
#customer specific fields
class Meta:
db_table = 'customer'
You can then have as many Users as you want from the UserProfile.
You should need just use Groups Django mechanism - you need to create two groups freelancer and let say common and check whether user is in first or second group - then show him appropriate view
To check whether user is in group you can use
User.objects.filter(pk=userId, groups__name='freelancer').exists()
You Could Try extending the Default Django Auth User like this
Create an App with Account or Whatever name you like , then in models.py write like below
class User(AbstractUser):
is_head = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_public = models.BooleanField(default=False)
Add Auth Extended Model in Settings.py
AUTH_USER_MODEL = 'accounts.User'
Migrate your Account app and you are all set with Your User Extended Model.

django admin. Create parent with child in same form

I have two classes in my model.py
class User(models.Model):
name = models.CharField()
phone = models.CharField()
# Other common fields
class Customer(User):
payment = models.CharField()
user__id = models.OneToOneField('User', db_column='id', primary_key=True)
class Company(User):
address = models.CharField()
user_id = models.OneToOneField('User', db_column='id', primary_key=True)
When I use the admin of Customer/Company it includes all User fields, that is perfect for me. But this form of Customer/Company also includes a dropdown list with the foreign key of an User, and I don't want to create the User first and then the Customer/Company object. I want that when I fill the Customer/Company form (with User fields) I should create the User object too.
Is there a way to solve this without create a User instance prior the Customer/Company instance?
Thanks
You can do this by adding an inline in your model registration in admin.py.
class AInline(admin.TabularInline):
model = A
class BAdmin(admin.ModelAdmin):
inlines = [AInline]
admin.register(A)
admin.register(B, BAdmin)
Django inline model admin documentation

Categories