I used the django debug toolbar to analyse why the calls to my usermodel were so painfully slow within the django admin. There I saw that I had hundreds of duplicate calls to the content_type model:
SELECT ••• FROM "django_content_type" WHERE "django_content_type"."id"
= 1 LIMIT 21
362 similar queries. Duplicated 4 times.
To be honest, I do not understand where these calls come from in the first place but I wanted to pre_fetch the model. However, this seems not to be possible in the normal way because there is actually no ForeignKey or any other kind of direct relationship between the models. How could I reduce those 362 content_type calls?
This is the usermodel in question:
class User(AbstractBaseUser, PermissionsMixin):
"""
Base model for the user application
"""
USERNAME_FIELD = "email"
objects = UserManager()
username_validator = None
username = None
email = models.EmailField(_("email address"), unique=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(default=timezone.now)
first_name = models.CharField(max_length=150, blank=True)
last_name = models.CharField(max_length=150, blank=True)
title_of_person = models.ForeignKey(
TitleOfPerson, on_delete=models.CASCADE, blank=True, null=True
)
is_verified = models.BooleanField(default=False)
language = models.ForeignKey(
Language, blank=True, null=True, on_delete=models.SET_NULL
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = _("User")
verbose_name_plural = _("Users")
def __str__(self) -> str:
return self.email
Thanks
Related
models.py
class User(AbstractBaseUser, PermissionsMixin):
BLOOD_GROUP_CHOICES = (
('a+','A+'),
('a-','A-'),
('b+','B+'),
('b-','B-'),
('ab+','AB+'),
('ab-','AB-'),
('o+','O+'),
('o-','O-')
)
BILLABLE_and_NON_BILLABLE_CHOICES=(
('Billable','Billable'),
('Non-Billable','Non-Billable')
)
username = models.CharField(max_length=30, unique=True,default=None)
email = models.EmailField(max_length=250, unique=True)
first_name = models.CharField(max_length=30, blank=True, null=True)
last_name = models.CharField(max_length=30, blank=True, null=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=True)
is_superuser = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
dob=models.DateField(max_length=8,default=None,null=True, blank=True)
pancard=models.CharField(max_length=25,default=None,null=True, blank=True)
aadhar=models.CharField(max_length=20,default=None,null=True, blank=True)
personal_email_id=models.EmailField(max_length=254,default=None,null=True, blank=True)
phone = PhoneNumberField(default=None,null=True, blank=True)
emergency_contact_no=models.IntegerField(default=None,null=True, blank=True)
emergency_contact_name=models.CharField(max_length=100,null=True, blank=True)
relation=models.CharField(max_length=25,default=None,null=True, blank=True)
blood_group=models.CharField(max_length=25,choices=BLOOD_GROUP_CHOICES,null=True,blank=True)
designation=models.ForeignKey(Designation,on_delete=CASCADE,related_name="designations",default=None,null=True, blank=True)
billable_and_non_billable=models.CharField(max_length=25,choices=BILLABLE_and_NON_BILLABLE_CHOICES,default='Billable',null=True, blank=True)
joining_date=models.DateField(max_length=15,null=True, blank=True)
relieving_date=models.DateField(max_length=15,null=True, blank=True)
is_manager=models.BooleanField(default=False)
reporting_manager = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE)
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email', ]
class Project(models.Model):
project_code = models.CharField(primary_key=False, max_length=10,default=None,null=True,unique=True)
project_name = models.CharField(max_length=50,unique=True,default=None)
client= models.ForeignKey(Client,on_delete=CASCADE,related_name="Client1",default=None)
user=models.ManyToManyField(User,related_name='users',default=None)
project_manager = models.ForeignKey(User,on_delete=models.PROTECT,related_name="project_manager",default=None,limit_choices_to = {'is_manager': True},null=True,blank=True)
description=models.TextField()
type=models.TextField() #dropdown
start_date = models.DateTimeField(max_length=10)
end_date=models.DateTimeField(max_length=10)
technical_contact_name = models.CharField(max_length=30)
email=models.EmailField(max_length=254,default=None)
phone = PhoneField(blank=True)
delivery_head_contact_name=models.CharField(max_length=30)
class Meta:
db_table ='Project'
def __str__(self):
if self.client is not None:
return f'{self.client.client_code }{self.project_code}-{self.project_name}'
else:
return self.project_code
class Timelog(models.Model):
STATUS_CHOICES = [
('created','Created'),
('submitted', 'Submitted'),
('approved', 'Approved'),
]
project = models.ForeignKey(Project,on_delete=CASCADE,related_name='project2',default=None)
user= models.ForeignKey(User,on_delete=CASCADE,related_name='user2',default=None,blank=True,null=True)
project_manager = models.ForeignKey(Project,on_delete=CASCADE,related_name='project_manager2',default=None,blank=True,null=True)
job=ChainedForeignKey(Job,chained_field="project", chained_model_field="project",show_all=False, auto_choose=True, sort=True)
date= models.DateField(default = datetime.date.today)
hours=models.DurationField(default=datetime.timedelta(),null=True)
status = models.CharField(max_length=20, choices=STATUS_CHOICES,null=False, default='Created')
def save(self, *args, **kwargs):
if not self.project_manager:
self.project_manager = self.project.project_manager
return super().save(*args, **kwargs)
class Meta:
db_table ='Timelog'
def __str__(self):
return '{}'.format(self.date)
As per my above code automatically i need to get the project managers of that specific project in the timelog model when i select the project and submit the timelog.
(for ex: If a user 'Vinoth' is a project Manager and other users are assigned on that project too, and I have a Project assigned to vinoth and the project name is 'API'. If a user enter a timelog they select the project 'API' and date and time, once they submit the request the project manager field needs to populate the project manager for that project automatically)
Can you please help me to complete this, as I tried by above method but it is throwing an error while migrating
"django.db.utils.IntegrityError: insert or update on table "Timelog" violates foreign key constraint "Timelog_project_manager_id_706fe60b_fk_Project_id"
DETAIL: Key (project_manager_id)=(2) is not present in table "Project"."
I dont know how to do this in other ways, kindly help me to fix this issue.
i have follwing structure:
class FullTreeAdminUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
class AdminFullTreeListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = FullTreeAdminUserSerializer
When i query users/all i have following error:
Cannot resolve keyword 'created' into field
The user model looks like
class User(AbstractBaseUser, PermissionsMixin):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
username = models.CharField(max_length=255, unique=True, db_index=True)
first_name = models.CharField(max_length=255, blank=True)
last_name = models.CharField(max_length=255, blank=True)
email = models.EmailField(max_length=255, unique=True, db_index=True)
is_verified = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
date_joined = models.DateTimeField(auto_now=True)
balance = models.FloatField(default=0.0)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
I cannot figure out where the problem is. I simply wanna get list of all user and i didn't expect such problems. I don't have created filed in my user model
I want to assign Tasks to only the staffs. Therefore, I want my dorpdown list should only show the users that have a role of is_staff = True.
But my drop down list now shows all the users (Superuser, Authority, General_user) that are available in the database.
How to modify this to only show staffs in the drop down list which should only show two users since I've assigned two users with staff role...?
My Model Classes:
Custom-User Model:
class User(AbstractBaseUser, PermissionsMixin):
"""
Responsible for handleing App user's data
"""
email = models.EmailField(max_length=255, unique=True)
nid = models.CharField(max_length=30, unique=True)
username = models.CharField(max_length=20, blank=True, null=True)
date_of_birth = models.DateTimeField(blank=True, null=True)
first_name = models.CharField(max_length=50, blank=True, null=True)
last_name = models.CharField(max_length=50, blank=True, null=True)
image = models.FileField(
upload_to=FileManager.photo_path, null=True, blank=True)
is_active = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_authority = models.BooleanField(default=False)
is_specialist = models.BooleanField(default=False)
is_general_user = models.BooleanField(default=False)
timestamps = models.DateTimeField(auto_now_add=True)
update = models.DateTimeField(auto_now=True)
objects = user_manager.UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['nid']
Tasks Model
class Task(BaseAbstractModel):
'''
Responsible for Storing and Providing Tasks data
'''
assignment = models.ForeignKey(Assignment,
on_delete=models.DO_NOTHING,
related_name='+')
assigne_to = models.ForeignKey(User,
on_delete=models.DO_NOTHING,
related_name='+')
task_name = models.CharField(max_length=300)
is_done = models.BooleanField(default=False)
created_by = models.ForeignKey(User,
on_delete=models.DO_NOTHING,
related_name='created_by')
Serializer:
class TaskListSerializer(serializers.ModelSerializer):
'''
Will be serializing Task's data
'''
created_by = UserListSerializer(read_only=True)
class Meta:
model = Task
fields = ('assignment',
'assigne_to',
'task_name',
'is_done',
'created_by',)
Generic Create View
class CreateTaskView(generics.CreateAPIView):
queryset = Task.objects.all()
serializer_class = TaskListSerializer
Try to use PrimaryKeyRelatedField with queryset argument:
class TaskListSerializer(serializers.ModelSerializer):
'''
Will be serializing Task's data
'''
created_by = UserListSerializer(read_only=True)
assigne_to = serializers.PrimaryKeyRelatedField(queryset=User.objects.filter(is_staff=True))
class Meta:
model = Task
fields = ('assignment',
'assigne_to',
'task_name',
'is_done',
'created_by',)
I have two models named user, skill, and profile.
I am trying to implement a search filter on the user's skills. which means when someone searches for something that is contained in the skills of a user, that user would appear in the search result.
Note: when the user signs up, a signal is used to auto-create a profile for that user. The user simply updates their profile to add skills and other things.
user model
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=254, unique=True)
name = models.CharField(max_length=250)
picture = models.TextField(null=True, blank=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
slug = models.SlugField(max_length=255, unique=True, blank=True)
profile model
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profiles')
date_of_birth = models.DateField(blank=True, verbose_name="DOB", null=True)
bio = models.TextField(max_length=500, blank=True, null=True)
skills = models.ManyToManyField(Skill, related_name='skills')
sex = models.CharField(max_length=6, choices=SEX, blank=True, null=True)
type_of_body = models.CharField(max_length=8, choices=BODYTYPE, blank=True, null=True)
feet = models.PositiveIntegerField(blank=True, null=True)
inches = models.PositiveIntegerField(blank=True, null=True)
lives_in = models.CharField(max_length=50, blank=True, null=True)
updated_on = models.DateTimeField(auto_now=True)
skill model
class Skill(models.Model):
name = models.CharField(max_length=60)
subcategory = models.CharField(max_length=60, blank=True, null=True)
description = models.TextField(null=True, blank=True)
created_on = models.DateTimeField(auto_now=True)
updated_on = models.DateTimeField(auto_now_add=True)
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.DO_NOTHING)
the user view, where the search is done from
class ListUsersView(generics.ListAPIView):
'''
Gets all the users in the database
'''
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [AllowAny]
filter_backends = [filtr.SearchFilter]
search_fields = ['email', 'name']
currently, the solution above works, but when I add to the search_fields other fields like profiles__skills in order to include results where there is a skill like that created by ay user, the code doesn't work.
Please, how can I get the skills in the profile of a user to show in the search?
The SearchFilter class supports simple single query parameter based searching. The search_fields attribute should be a list of names of text type fields on the model.
profiles__skills is not a field. You should use a text field eg. profiles__skills__name
class ListUsersView(generics.ListAPIView):
'''
Gets all the users in the database
'''
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [AllowAny]
filter_backends = [filtr.SearchFilter]
search_fields = ['email', 'name', 'profiles__skills__name']
I have the following models:
class Address(models.Model):
address1 = models.CharField(max_length=150, null=True)
address2 = models.CharField(max_length=150, null=True, blank=True)
city = models.CharField(max_length=50, null=True)
state_province = models.CharField(max_length=50, null=True)
zipcode = models.CharField(max_length=10, null=True)
country = models.CharField(max_length=3, default='USA', null=False)
created_at = models.DateTimeField(db_index=True, auto_now_add=True)
updated_at = models.DateTimeField(db_index=True, auto_now=True)
class Meta:
db_table = 'addresses'
and this one.....
class User(models.Model, AbstractBaseUser, PermissionsMixin):
email = models.EmailField(db_index=True, max_length=150, unique=True,
null=False)
first_name = models.CharField(max_length=45, null=False)
last_name = models.CharField(max_length=45, null=False)
mobile_phone = models.CharField(max_length=12, null=True)
profile_image = models.CharField(max_length=150, null=True)
is_staff = models.BooleanField(db_index=True, null=False, default=False)
is_active = models.BooleanField(
_('active'),
default=True,
db_index=True,
help_text=_(
'Designates whether this user should be treated as active. '
'Unselect this instead of deleting accounts.'
),
)
addresses = models.ManyToManyField(Address),
USERNAME_FIELD = 'email'
objects = MyCustomUserManager()
def __str__(self):
return self.email
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
class Meta:
db_table = 'users'
My first mystery is that by migrating the models, there is no "addresses" field in the users table, nor a pivot table in the database to keep the multiple relationships. How are ManyToMany payloads kept??
Secondly, my goal is to have multiple addresses for Users. I want Users to have multiple "Addresses" (and not each address having one User) because other models can have addresses too. I don't want the Address model to have 12 different "owner" fields with with ForeignKeys.
So. I try this:
from myApp.models import User
from myApp.models import Address
user = User(email="test#test.com", first_name="john", last_name="doe", mobile_phone="444")
# the model permits partial address fields, don't worry about that.
address = Address(city="New York", zipcode="10014")
Now I try to add the address to the user.addresses and I'm getting an error.
user.addresses.add(address)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-0337af6b1cd4> in <module>()
----> 1 user.addresses.add(address)
AttributeError: 'tuple' object has no attribute 'add'
Help?
You have a superfluous comma after the definition of the many-to-many field, which turns it into a tuple. When you've removed this, you'll find both that the migrations will create your intermediary table, and that user.addresses.add() will work.