I'm working on an existing Django project in Django 1.4. I want to upgrade to Django 1.5 for implementing a custom user model. I have to ensure that my existing information is not deleted from the database(Postgres 9.1).
This post explains the steps to be done for data migration using South but only for AbstractUser. I have to use AbstractBaseUser. Is there any way?
My existing model is like :
class Individual(models.Model):
user = models.ForeignKey(User, unique=True, blank=True, null=True)
parent = models.ForeignKey('self', unique=True, blank=True, null=True)
....(some many to many and foreign key)
I want to change it to something like this.
class User(AbstractBaseUser, Individual, PermissionsMixin):
email = models.EmailFeild(max_length=50, unique=True)
is_admin = models.BooleanField(default=False)
username = models.CharField(max_length=50,unique=True)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
The individual class will contain all previous fields except the user. How can I go about doing this?
Document how to migrate from a built-in User model to a custom User model thread has some workaround discussions.
Related
I ran into a problem
I am making a job search site on Django, I have the following logic:
Authorization and authentication of ordinary job seekers using Django's built-in model - User
Also separate authorization and authentication for users who provide work, i.e. employers,
which are placed in my own model Employer
Here is my Employer model
class Employer(AbstractUser):
full_name = models.CharField(max_length=150, verbose_name="Ім'я")
main_office_city = models.ForeignKey(City, on_delete=models.CASCADE,
verbose_name='Місто головного офісу')
phone_number = models.ForeignKey(Phone, on_delete=models.CASCADE)
email = models.CharField(max_length=50, unique=True, verbose_name='Email')
hashed_password = models.CharField(max_length=120, default='')
date_joined = models.DateTimeField(verbose_name='Дата реєстрації',
default=timezone.now)
def __str__(self):
return self.full_name
class Meta:
verbose_name = 'Роботодавець'
verbose_name_plural = 'Роботодавці'
I read in the documentation that to create your own authentication system you can use the imitation from the AbstractUser class
But in my case this is not the best choice, because AbstractModel adds its own fields by default.
That is, I think that I need to either somehow make it so that the AbstractUser class does not add its fields, or think of some other authentication logic using another technology
Maybe someone has some ideas how it can be done?
I was trying to build an application in Django. see my requirements. The company will have multiple branches, and staff also work for one more branches in different roles. For example, they may work in branch-A as a sales manager and branch -b as a Branch Manager, I was trying to implement that by Django Group and Permission, ( I use custom permissions instead of Group permission). Please see my model classes
#Branches
class Branch(models.Model):
branch_code=models.CharField(max_length=100,unique=True)
address=models.CharField(max_length=200)
delete_status=models.IntegerField(choices=BRANCH_CHOICES,default=LIVE)
published_date = models.DateTimeField(blank=True, null=True)
# Roles on Branch
class BranchRole(models.Model):
owner_branch = models.ForeignKey(Branch,on_delete=models.CASCADE,related_name='available_groups')
available_group = models.ForeignKey(Group,on_delete=models.CASCADE)
class User(AbstractUser):
"""User model."""
username = None
email = models.EmailField(_('email address'), unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
class StaffUser(models.Model):
staff_id=models.CharField(max_length=100,null=True,)
name=models.CharField(max_length=100,null=True)
user=models.OneToOneField(User, on_delete=models.CASCADE,related_name='staffs')
class RoleInBranch(models.Model):
branch_role=models.ForeignKey(BranchRole,on_delete=models.CASCADE,related_name='assigned_role')
permissions=models.ManyToManyField(Permission,related_name='allowed_staffs_in_branch')
role_owner=models.ForeignKey(StaffUser,on_delete=models.CASCADE,related_name='roles',null=True)
Here I am getting permission id and staff object, but I need to find all branches which are having that particular permission (for that requested staff object).
I tried this
Branch.objects.filter(available_groups__assigned_role__permissions=permission_obj,available_groups__assigned_role__role_owner=staff_obj)
please help me to find the exact solution
I have custom user model:
class User(AbstractUser):
"""
Our own User model. Made by overriding Django's own AbstractUser model.
We need to define this as the main user model in settings.py with
variable AUTH_USER_MODEL *IMPORTANT*
"""
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField(
max_length=255,
unique=True,
verbose_name="email address"
)
institute = models.ForeignKey(
Institute, on_delete=models.SET_NULL, null=True)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
def __str__(self):
return self.email
I have two users in my projects. One is the super admin and the other is the admin. I've specified the model for admin as such:
class AdminUser(User):
is_admin = False
is_staff = True
def __str__(self):
return self.first_name+" "+self.last_name
# Control model features
class Meta:
verbose_name = 'Admin User'
verbose_name_plural = 'Admin Users'
Now I want to revoke access of the entire user model from this Admin User. How could this be achieved? We are going to have many more user types in future. They will be specified through models.
You can achieve this by just using groups in Django.
Your superuser will be you, that will have all permissions for default using the field is_admin=True. The second user can be a simple Staff user that is member of the group "Admins", just create the group and assign all the permissions to that group except the permissions to Add, Change and Delete users.
That will do the trick.
Update: If you need more complex cases, you can use the app django-groups-manager or django-guardian So you can create groups in trees, there you can use more domain driven permission rules.**
I have a model named UserProfile and a model PersonalInformation. I would like to fetch all the data of PersonalInformation using UserProfile model when the user is logged into the webiste but i have a foreign key refernce in the PersonalInformation model with the UserProfile model so how do i fetch the personal information using UserProfile model?
User Profile Model :
class UserProfile(models.Model):
"""Represents a user's model inside our system"""
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
profile_picture = models.ImageField(upload_to='photos/%y/%m/%d/')
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
highest_degree_earned = models.CharField(max_length=255, blank=False)
college_name = models.CharField(max_length=255, blank=False)
graduation_year = models.IntegerField(default=2020, blank=False)
Personal Information Model :
class PersonalInformation(models.Model):
"""Represents a user's personal Infromation inside our system"""
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
mobile = models.CharField(max_length=10 ,blank=True)
bio = models.TextField(max_length=200, blank=True)
college_university = models.CharField(max_length=100, blank=False)
course = models.CharField(max_length=100, blank=False)
First of all, in the code, you are showing you have the names of the models wrong. The UserProfile model name is set as PersonalInformation, change it or the migrations won't work (it's not accepted on the database no matter which one you're using).
Referent to the question you're asking, to fetch the related instance of PersonalInformation of a certain UserProfile instance you should just query the next:
user = UserProfile.objects.get(id='') #Introduce the id of the user you want to fetch its personal information.
user.personalinformation_set.all() # This will return you a QuerySet with all the related instances of PersonalInformation class.
user.personalinformation_set.get(id='') #To get a specific one or you may use a filter to get a filtered QS.
If you want, you can use the related_name attribute for ForeignKey class in order to set a different name from personalinformation_set.
I recommend you too to read the Django documentation, it's really well explained and clear I think:
https://docs.djangoproject.com/en/2.2/topics/db/examples/many_to_one/
As I've seen in a comment, you may also think to use a OneToOne relation instead of ForeignKey if you only expect one instance of PersonalInformation per User. The documentation is at:
https://docs.djangoproject.com/en/2.2/topics/db/examples/one_to_one/
I'm trying to set up an app that will handle reviews about registered users. So in my Review model, I want to have a ForeignKey to my User model.
I'm using a custom user profile that looks like this:
#In /profiles/models.py
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
company = models.CharField(default="", max_length=200)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['company']
I have included it with settings.py AUTH_USER_MODEL = "profiles.MyUser". It works fine with registration, creating users etc. So I know its working.
In my review model I write the following:
class Review(models.Model):
company = models.ForeignKey(settings.AUTH_USER_MODEL)
reviewer = models.ForeignKey(Reviewer)
rating = models.IntegerField(default=0)
review = models.TextField()
pub_date = models.DateTimeField('date published')
Instead of settings.AUTH_USER_MODEL I have also tried writing profiles.MyUser, 'profiles.MyUser' and MyUser.
I can successfully use the python manage.py makemigrations reviews command. But when I do python manage.py migrate I get errors no matter what version I use above.
The error I get is the following:
ValueError: Lookup failed for model referenced by field reviews.Review.company: profiles.MyUser
nejc92 comment was correct. I had migrated my database earlier before I set AUTH_USER_MODEL for the first time.
I removed my whole database and created new migrations for all apps and migrated everything again from scratch. It then worked.
Sounds like a bug(?) to me.