How to implement switch accounts option in Django - django

Consider an application where there is a company account and employee account. I want to add employees as admin of the company. Then the admin should be able to switch account with the company. Is it possible to do the switch account option?
I am a beginner in Django. Can anyone help me with this problem?
I am adding my user model here:
# Custom user
class CustomUser(AbstractUser):
""" Custom user model"""
email = models.EmailField(unique=True, validators=[EmailValidator])
is_company = models.BooleanField(default=True)
is_employee = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
slug = AutoSlugField(populate_from='username')
def __str__(self):
return f"{self.username}"
# Company user
class CompanyAccount(TimeStampedModel):
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, related_name='company')
name = models.CharField(max_length=50, null=True, blank=True)
description = models.TextField(null=True, blank=True)
email = models.EmailField(null=True, blank=True)
website_url = models.URLField(null=True, blank=True)
industry = models.CharField(max_length=50, null=True, blank=True)
founded_year = models.PositiveSmallIntegerField(blank=True, null=True)
headquarters = models.CharField(max_length=100, null=True, blank=True)
def __str__(self):
return f"{self.name}"
# Employee user
class Employee(TimeStampedModel):
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, related_name="profile")
first_name = models.CharField(max_length=50, null=True, blank=True)
last_name = models.CharField(max_length=50, null=True, blank=True)
city = models.CharField(max_length=100, null=True, blank=True)
country = models.CharField(max_length=100, null=True, blank=True)
job_title = models.CharField(max_length=100, null=True, blank=True)
company = models.ForeignKey(CompanyAccount, on_delete=models.CASCADE, related_name="employee")
def __str__(self):
return f"{self.user.username}"

Related

I receive an error while migrating my models to a database

I get such an error while migrating to a database:
return Database.Cursor.execute(self, query)
django.db.utils.OperationalError: foreign key mismatch - "user_auth_customer"
referencing "user_auth_profile"
I have checked Foreign_Keys of my models and they look good.
I have no idea why I receive that error :(
Please, help me out here.
class Customer(AbstractUser):
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
profile = models.OneToOneField("Profile", related_name="user_profile",
on_delete=models.CASCADE, null=True)
first_name = models.CharField(max_length=50, null=True, blank=True)
last_name = models.CharField(max_length=50, null=True, blank=True)
username = models.CharField(max_length=30, null=True, blank=True)
phone = models.CharField(max_length=10, default='', null=True, blank=True)
email = models.EmailField(validators=[validators.EmailValidator()],
unique=True)
password = models.CharField(max_length=100, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
#staticmethod
def get_customer_by_email(email):
try:
return Customer.objects.get(email=email)
except:
return False
def isExists(self):
if Customer.objects.filter(email=self.email):
return True
return False
class Meta:
verbose_name = 'Customer'
verbose_name_plural = 'Customers'
class Profile(models.Model):
first_name = models.CharField(max_length=50, null=True, blank=True)
last_name = models.CharField(max_length=50, null=True, blank=True)
phone = models.CharField(max_length=10, default='', null=True, blank=True)
email = models.EmailField(primary_key=True, unique=True, validators=[validators.EmailValidator()])
password = models.CharField(max_length=100, null=True, blank=True)
# Add a photo field
owner = models.OneToOneField(Customer, related_name='profile_owner',
on_delete=models.SET_NULL, null=True)
username = models.CharField(max_length=30, null=True, blank=True,
validators=[UnicodeUsernameValidator()])
date_created = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'Profile'
verbose_name_plural = 'Profiles'
if you need any else details, I can provide you with those in the comments.
You can't have both ways OneToOneField. Choose one way.
If you delete Customer's profile field, then still you will have possibility to call relation with:
customer = Customer.objects.get(id=1)
customer.profile # that will call Customer's related Profile object
Assuming, that you will change related_name='profile_owner' to simpler related_name='profile'.
Read more about OneToOneRelationships.

How to display one models data in another model django admin panel

I have two models: 1) SchoolProfile & 2) Content
I want to show content data in schoolprofile, But data should be display as per user foreignkey.
User foreignkey common for both the models.
School Profile Model
class SchoolProfile(models.Model):
id=models.AutoField(primary_key=True)
user=models.ForeignKey(User,on_delete=models.CASCADE,unique=True)
school_name = models.CharField(max_length=255)
school_logo=models.FileField(upload_to='media/', blank=True)
incharge_name = models.CharField(max_length=255, blank=True)
email = models.EmailField(max_length=255, blank=True)
phone_num = models.CharField(max_length=255, blank=True)
num_of_alu = models.CharField(max_length=255, blank=True)
num_of_student = models.CharField(max_length=255, blank=True)
num_of_cal_student = models.CharField(max_length=255, blank=True)
def __str__(self):
return self.school_name
Content Model
class Content(models.Model):
id=models.AutoField(primary_key=True)
user=models.ForeignKey(User,on_delete=models.CASCADE)
content_type = models.CharField(max_length=255, blank=True, null=True)
show=models.ForeignKey(Show,on_delete=models.CASCADE, blank=True, null=True)
sponsor_link=models.CharField(max_length=255, blank=True, null=True)
status=models.BooleanField(default=False, blank=True, null=True)
added_on=models.DateTimeField(auto_now_add=True)
content_file=models.FileField(upload_to='media/', blank=True, null=True)
title = models.CharField(max_length=255)
subtitle = models.CharField(max_length=255, blank=True, null=True)
description = models.CharField(max_length=500, blank=True, null=True)
draft = models.BooleanField(default=False)
publish_now = models.CharField(max_length=255, blank=True, null=True)
schedule_release = models.DateField(null=True, blank=True)
expiration = models.DateField(null=True, blank=True)
tag = models.ManyToManyField(Tag, null=True, blank=True)
topic = models.ManyToManyField(Topic, null=True, blank=True)
category = models.ManyToManyField(Categorie, null=True, blank=True)
def __str__(self):
return self.title
I have used Inline but it's show below error:
<class 'colorcast_app.admin.SchoolProfileInline'>: (admin.E202) 'colorcast_app.SchoolProfile' has no ForeignKey to 'colorcast_app.SchoolProfile'.
My admin.py
class SchoolProfileInline(InlineActionsMixin, admin.TabularInline):
model = SchoolProfile
inline_actions = []
def has_add_permission(self, request, obj=None):
return False
class SchoolProfileAdmin(InlineActionsModelAdminMixin,
admin.ModelAdmin):
inlines = [SchoolProfileInline]
list_display = ('school_name',)
admin.site.register(SchoolProfile, SchoolProfileAdmin)
Using the StackedInline to link two models is straight forward and a much clean practice, so basically this is my solution below:
class ContentInlineAdmin(admin.StackedInline):
model = Content
#admin.register(SchoolProfile)
class SchoolProfileAdmin(admin.ModelAdmin):
list_display = ('school_name',)
inlines = [ContentInlineAdmin]

django RelatedObjectDoesNotExist error while creating

models:
class FullNameMixin(models.Model):
name_id = models.BigAutoField(primary_key = True, unique=False, default=None, blank=True)
first_name = models.CharField(max_length=255, default=None, null=True)
last_name = models.CharField(max_length=255, default=None, null=True)
class Meta:
abstract = True
class Meta:
db_table = 'fullname'
class User(FullNameMixin):
id = models.BigAutoField(primary_key = True)
username = models.CharField(max_length=255, unique=True)
email = models.CharField(max_length=255, unique=True)
token = models.CharField(max_length=255, unique=True, null=True, blank=True)
password = models.CharField(max_length=255)
role = models.IntegerField(default=1)
verified = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, null=True, blank=True)
def __str__(self):
return self.username
class Meta:
db_table = 'cga_user'
class Profile(FullNameMixin):
id = models.BigAutoField(primary_key = True)
birthday = models.DateTimeField(null=True, blank=True)
country = models.CharField(max_length=255, null=True, blank=True)
state = models.CharField(max_length=255, null=True, blank=True)
postcode = models.CharField(max_length=255, null=True, blank=True)
phone = models.CharField(max_length=255, null=True, blank=True)
profession_headline = models.CharField(max_length=255, null=True, blank=True)
image = models.ImageField(upload_to=get_upload_path, null=True, blank=True)
profile_banner = models.ImageField(upload_to=get_upload_path_banner, null=True, blank=True)
cga_user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE, related_name="profile")
gender = models.CharField(
max_length=255, blank=True, default="", choices=USER_GENDER_CHOICES
)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, null=True, blank=True)
class Meta:
db_table = 'profile'
When i am creating Profile from django admin panel getting below error.
e
filename = self.upload_to(instance, filename)
File "/Users/soubhagyapradhan/Desktop/upwork/africa/backend/api/model_utils/utils.py", line 7, in get_upload_path
instance.user,
File "/Users/soubhagyapradhan/Desktop/upwork/africa/backend/env/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 421, in __get__
raise self.RelatedObjectDoesNotExist(
api.models.FullNameMixin.user.RelatedObjectDoesNotExist: Profile has no user.
[24/Jul/2021 13:49:51] "POST /admin/api/profile/add/ HTTP/1.1" 500 199997
please take a look how can i fix this.
Note: User model creation working but, profile not working
I checked in drf and django admin panel .
both place not working.
The problem here is that you are declaring a User model which is in fact just a model. That's not how it works.
The User is a special type of model and if you want to change it you have to extend the AbstractUser class.
Alternatively you can connect to it via one-to-one classes in the classic user-profiles approach.
But here you are creating a user model that (besides using the reserved word 'User') has none of the requirements necessary to be treated as a user who can be authenticated and that can instantiate sessions.
> Example of a simple user-profiles architecture
> Working with User objects - Django Docs (i particularly recommend this one)
I would recommend you to read-up on django user authentication.

FOREIGN KEY constraint failed in signals

I tried to insert data into the table Account, but I keep getting this error message.
I delete all my migrations and make migrations again but I keep getting this error.
Here is my models.
class Student(models.Model):
user = models.OneToOneField(Account, on_delete=models.CASCADE)
name = models.CharField(max_length=50, null=True, blank=True)
phone = models.CharField(max_length=15, blank=True, null=True)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, blank=True, null=True)
section = models.ForeignKey(Section, on_delete=models.CASCADE, default=1)
dept = models.ForeignKey(Dept, on_delete=models.CASCADE, blank=True, null=True)
batch = models.CharField(max_length=15, null=True, blank=True)
USN = models.CharField(primary_key='True', max_length=100)
DOB = models.DateField(default='1998-01-01')
profile_image = models.ImageField(upload_to='student/profile_images/%Y/%m/%d/', blank=True, null=True)
address = models.CharField(max_length=300, null=True, blank=True)
nationality = models.CharField(max_length=100, null=True, blank=True)
guardian_name = models.CharField(max_length=200, null=True, blank=True)
guardian_number = models.CharField(max_length=15, null=True, blank=True)
guardian_address = models.CharField(max_length=300, null=True, blank=True)
blood_group = models.CharField(max_length=3, null=True, blank=True)
exam_name = models.CharField(max_length=300, null=True, blank=True)
background = models.CharField(max_length=300, null=True, blank=True)
passing_year = models.CharField(max_length=8, null=True, blank=True)
score = models.CharField(max_length=10, null=True, blank=True)
school_name = models.CharField(max_length=300, null=True, blank=True)
country = models.CharField(max_length=100, null=True, blank=True)
certificate = models.FileField(upload_to='certificates/%Y/%m/%d/', null=True, blank=True)
Here is Account model.
class Account(AbstractBaseUser, PermissionsMixin):
unid = models.CharField(max_length=20, unique=True, null=True, blank=True)
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=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)
is_student = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=False)
group = models.ForeignKey(Group, on_delete=models.CASCADE, null=True, blank=True)
user_permissions = models.ManyToManyField(
Permission,
verbose_name=_('user permissions'),
blank=True,
null=True,
help_text=_('Specific permissions for this user.'),
related_name="user_set",
related_query_name="user",
)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
registered = models.BooleanField(default=False)
so what I did is that when I create account if the is_student is True I create a signals that going to create student model for that account instance automatically.
here is the signals
def create_student_or_teacher(sender, created, instance, **kwargs):
if created:
if instance.is_student:
Student.objects.create(
user=instance,
USN=instance.unid,
)
elif instance.is_teacher:
Teacher.objects.create(
user=instance,
id=instance.unid,
)
So when I create the account for student the tracker will highlight in the signals Student.objects.create(...)
If you have any idea I hope it would help me.
UPDATED:
When I'm creating teacher it is working find.
here is the teacher model
class Teacher(models.Model):
name = models.CharField(max_length=50, null=True, blank=True)
phone = models.CharField(max_length=15, blank=True, null=True)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, blank=True)
salary = models.IntegerField(default=1)
school = models.ForeignKey(School, blank=True, null=True, on_delete=models.CASCADE)
section = models.ForeignKey(Section, blank=True, null=True, on_delete=models.CASCADE)
user = models.OneToOneField(Account, on_delete=models.CASCADE, null=True)
id = models.CharField(primary_key=True, max_length=100)
dept = models.ForeignKey(Dept, on_delete=models.CASCADE, blank=True, null=True)
DOB = models.DateField(default='1980-01-01')
profile_image = models.ImageField(upload_to='teacher/profile_images/%Y/%m/%d/', blank=True, null=True)
nationality = models.CharField(max_length=300, null=True, blank=True)
address = models.CharField(max_length=300, null=True, blank=True)
Finally after few hours I solved my error it was simple
in the section I set default value which was not exist
so I just change the value to an exist one and that was it.

What am I missing in this Django model relationship

I have a CustomUser model, and a Blog model.
CustomUser model:
class CustomUser(AbstractUser):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=20, default="", blank=True)
last_name = models.CharField(max_length=20, default="", blank=True)
address = models.CharField(max_length=150, default="", blank=True)
city = models.CharField(max_length=20, default="", blank=True)
zip_code = models.CharField(max_length=20, default="", blank=True)
country = models.CharField( max_length=50, default="", blank=True, choices=settings.COUNTRIES_LIST)
about_me = models.TextField(max_length=225, default="", blank=True)
photo_url = models.TextField(null=True)
is_active = models.BooleanField(default=True) # can login
Blog model:
class Blog(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, null=True, verbose_name=_('user'), related_name="%(class)s_blogs", on_delete=models.SET_NULL)
blog_id = models.CharField(max_length=150, null=False, default=get_id, unique=True, editable=False)
blog_title = models.CharField(max_length=150, null=False)
blog_description = models.TextField(max_length=300, null=True, blank=True)
created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True, auto_now_add=False)
blog = FroalaField()
dynamic_link = models.CharField(max_length=225, null=False, default="")
blog_type = models.CharField( max_length=50, null=False, choices=BLOGSTYPE_LIST)
blog_status = models.CharField(max_length=150, null=False, default="unapproved")
is_active = models.BooleanField(default=False)
is_featured = models.BooleanField(default=False)
My understanding is that I could use the related_name to get all blogs by a user.
>>> from users.models import CustomerUser
>>> user = CustomUser.objects.get(pk=1)
>>> user.blog_blogs.all()
<BlogQuerySet []>
As you must have seen, this turns to always return but an empty queryset, even though there are blog entries by that user.
So is it am not understanding here?
Thank you.