Currently i'm starting with a user management app.
The case is that we have models User (the default django user model) and an UserMail.
The UserMail has an OneToOneField to User with reference to the field username.
mail_username= models.OneToOneField(
User,
to_field='username',
on_delete=models.CASCADE)
Because we also use the database of UserMail for another app, I want the password to be in the same table, which would look like this:
mail_password = models.CharField(max_length=128)
But the mail_password has to be the password from the corresponding User.username. So if we choose an user from the User model, the password of that user should also be filled in the mail_password field
Is there a nice way to do this?
Related
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.
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 make models for user auth(use abstract user) for login and signup using Django?
I want to make login OTP based for ecommerse website.
from django.db import models
class User(models.Model):
first_name = models.CharField(max_length=40)
last_name = models.CharField(max_length=40)
mobile = models.CharField(max_length=10)
address = models.CharField(max_length=200)
emailId = models.CharField(max_length=50)
password = models.CharField(max_length=200)
I tr above code.
What should I have to add above?
You should use AbstractUser if you want to inherit permissions settings and all functions that Django uses.
In settings, you should also add AUTH_USER_MODEL = "your_module_name.User"
In Django, making a user model by yourself is not recommended because other 3rd party packages depend on the user models Django provided.
There are two ways you can follow.
Extending the existing User model
Using a custom user model when starting a project
I know that superusers and regular users are both just django's User objects, but how can I write a custom user class that requires some fields for plain users and doesn't require those fields for superusers?
No structure in the database is tricky. JSONFields for example may prove to be extremely hard to tame when the app grows.
I would go and try to make it "simple" - more maintainable (I imagine if you need to do stuff like that you may want to extend the model in the future). If this is a new project you can easily change the default user model. But that may or may not help you with your case.
You can always make two models:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
class Mortal(AbstractBaseUser):
is_superuser = False
username = models.CharField(max_length=256)
first_name = models.CharField(max_length=256)
last_name = models.CharField(max_length=256)
class Admin(AbstractBaseUser):
is_superuser = True
username = models.CharField(max_length=256)
and then make your own authentication backend:
class MyBackend(object):
"""
Danger! A backend to authenticate only via username
"""
def authenticate(self, username=None):
try:
return Mortal.objects.get(username=username)
except Mortal.DoesNotExist:
try:
return Admin.objects.get(username=username)
except Admin.DoesNotExist:
return None
You can have a profile class (say UserProfile) with foreign key to the user that is to be created only when user signs up using the website's registration form. That way, superuser which is created on admin site or through command line wouldn't need an extra profile instance attached to it.
I have managed to add an additional field to the Registration form, "where did you hear about us?".
But I am not sure which files to edit in order to store the data from this field along with the users info.
i.e. When logging into the Admin section and go to "users" and view a users info I would like to see this field there.
Simplest way would be to store additional data in a UserProfile model about the user, e.g.
from django.contrib.auth.models import User
class UserProfile(models.Model):
# This field is required.
user = models.OneToOneField(User)
# Other fields here
where_heard_about_us = models.TextField()
You can then register the object as an inline object in your Django Admin