I have 2 database tables, Prospects and Profile. They're related by a One-to-one foreign key relationship
Model.py
class Prospect(models.Model):
profile = models.OneToOneField(Profile, on_delete=models.CASCADE, null=True, blank=True, related_name="profile_prospects")
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
In my view.py
prospects = prospects[:50]
I have a QuerySet of prospects (prospects is working correctly, exactly what I want), and I would like to retrieve a QuerySet of profiles based on the database model above. I tried
profiles = Profile.objects.filter(profile_prospects__in = prospects)
It returns an error of
django.db.utils.ProgrammingError: subquery has too many columns
How can I get all the relevant profiles?
You have spaces in
profiles = Profile.objects.filter(profile_prospects__in = prospects)
Sorry, I might be confused here. But isn't the profile automatically inherited by the prospect since it's a one-to-one relationship?
When you have the prospect you should be able to get the profile like this
prospect.profile
Again, I might have gotten the question wrong.
Related
There is 2 models Registration and RegistrationCompletedByUser, I want Registration queryset from RegistrationCompletedByUser with filters(user=request.user, registration__in=some_value, is_completed=True) over RegistrationCompletedByUser. Hence result should be like <QuerySet [<Registration: No name>, <Registration: p2>, <Registration: p-1>]>.
Now what I tried is
Registration.objects.prefetch_related('registrationcompletedbyuser_set') but filters() not working. Another way I tried is model Managers but don't pass parameters for custom filtering.
models.py
class Registration(models.Model):
name=models.CharField(max_length=255)
number=models.SmallIntegerField(null=True, blank=True)
class RegistrationCompletedByUser(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
registration= models.ForeignKey(Registration, on_delete=models.CASCADE)
points = models.SmallIntegerField(default=100)
is_completed = models.BooleanField(default=False)
If I understood this properly, you want to get all Registrations that related to a query instead of a single object.
qs_1 = RegistrationCompletedByUser.objects.filter(user=request.user, is_completed=True).values_list("registration__id", flat=True)
qs_2 = Registration.objects.filter(id__in=qs_1)
As I understood your question is related to django. So actually there is common way to get related query set from another. When you specify ForeignKey to another model actually django automatically creates 'Related Model' + '_set' relation.
I actually didn't get from you question what you are intended to do. In your situation there are many RegistrationCompletedByUser related to one Registration. So what you can do it's to receive all RegistrationCompletedByUser instances from Registration instance by related name for ForeignKey registration of RegistrationCompletedByUser which in your case registration_set. Actually better to specify in RegistrationCompletedByUser model related name as attribute like this:
models.ForeignKey(Registration, on_delete=models.CASCADE,
related_name='registrations')
And after this let's say you have instance of Registration reg1. So to receive queryset of RegistrationCompletedByUser:
reg1.registrations.all()
And you can use filter on it with attributes from Registration model.
And if you want to receive Registration from RegistrationCompletedByUser, again in your case it's just one Registration to many RegistrationCompletedByUser, so let's say we have reg_completed_1, to receive it's only one registration:
reg = reg_completed_1.registration
I'm working on Django 1.10 and PostgreSQL9.6
I have two models in my project: Order and Customer. Also I'm using Django's auth.User to store login credentials.
Here is a code snipped:
from django.contrib.auth.models import User
from django.db import models
class Order(models.Model):
created_by = models.ForeignKey(User, null=True, on_delete=models.SET_NULL, related_name='created_orders')
# ... other fields ...
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
# ... other fields ...
Now, I need to show a table of customers and show a number of orders created by each of them.
The staight forward code is:
for customer in Customer.objects.all():
print(customer.user.created_orders.count())
Now I need to avoid N+1 problem and make Django to fetch all data with constant number of queries.
I've tried to write something like:
query = Customer.objects.select_related('user').annotate(
orders_count=Count('user.created_orders')
)
But this gives me an error like Cannot resolve keyword 'user.created_orders' into field.
Can you help me with this?
You should not use a dot (.) here, but two consecutive underscores (__):
query = Customer.objects.select_related('user').annotate(
orders_count=Count('user__created_orders')
)
Note that you do not need to .select_related('user') in order to annotate a queryset. If you however plan to use the .user later in your logic, it can indeed boost performance.
I want to assign many Region to the UserProfile model, how to do it?
the code
class Region(models.Model):
name = models.CharField(max_length=30)
created_at = models.DateTimeField(auto_now=True)
class UserProfile(models.Model):
user = models.OneToOneField(
region = models.ForeignKey(Region, on_delete=models.CASCADE, null=True, blank=True)
The relation you describe is not a ForeignKey, which means that a UserProfile has (at most) one related Region, but a ManyToManyField [Django-doc].
A ManyToManyField thus means that a region can be related to zero, one, or more UserProfiles, and a UserProfile can be related to zero, one, or more Regions.
You can thus change the models to:
class Region(models.Model):
name = models.CharField(max_length=30)
created_at = models.DateTimeField(auto_now=True)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
regions = models.ManyToManyField(Region)
In a relational database this is implemented by adding an extra (hidden) table with ForeignKeys to Regions and UserProfiles. But the Django ORM works in a "transparant" way and thus hides the implementation details.
See the documentation for more information on how to "populate" such relation.
from django.contrib.auth.models import AbstractUser
class UserProfile(AbstractUser):
regions = models.ManyToManyField(Region,related_name='User')
I think this is the ideal way to implement what you need. Using ManyToManyField allows you to map userprofile object to more than one region object and vice versa.
Also, Inheriting Abstract User allows you to add region field to Django User Table, which is better than creating another table for linking user to and region field.
I have some two models (in different apps/models.py files) related with User:
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, null=False)
...
class CourseStudent(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
semester = models.ForeignKey(Semester)
...
I am trying to get a queryset of all profiles that have at least one course in the current semester.
How can I generate a queryset of profiles, where profile.user has at least one CourseStudent instance, and filtered so that coursestudent.semester=current_semester?
Since a student may have multiple courses in the semester, the duplicates also need to be removed (unique profiles only in the queryset)
EDIT: I am using postgresql and trying to figure out if I need to use distinct with an argument.
Not tested. Maybe you should try
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, null=False)
...
class CourseStudent(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="course_student")
semester = models.ForeignKey(Semester)
Profile.objects.filter("what_you_want").exclude(user__courser_student=None).distinct()
I have a profile table which have a foreign key of the user.
class Profile(models.Model):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
image = models.CharField(max_length=100)
user = models.ForeignKey(User)
I also have a COMMENT table which have a foreign key of the user.
class Comment(models.Model):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
content = models.TextField()
user = models.ForeignKey(User)
I want to query the table COMMENT and also I want to get the image of the user which is in the PROFILE table. How can I query this in most effective way in django?.
thanks
If you are okay with changing ForeignKey to OneToOneField on Profile model then you can do it like,
Comment.objects.all().select_related('user__profile')
The above one selecting additional related-object data when it executes its query. This is a performance booster which results in a single more complex query but means later use of foreign-key relationships won’t require database queries.
Otherwise you can get it this way
for comment in Comment.objects.all():
print comment.user.profile_set.all()[0].image
If you're using Django = <1.4 the following is best practice:
comment = Comment.objects.get(pk=1)
comment.user.get_profile().image
Following the deprecation of native Profile model support (Django 1.5+) the following is still possible:
comment = Comment.objects.get(pk=1)
comment.user.profile.image
Django 1.5+ introduces custom auth models so you can do the following:
comment = Comment.objects.get(pk=1)
comment.user.image
At very least you should change your ForeignKey to a OneToOne relation for the user column on Profile, as Django =< 1.4 expects only one User Profile to be associated with a User.
References:
Django 1.4 get_profile: https://docs.djangoproject.com/en/1.4/topics/auth/#django.contrib.auth.models.User.get_profile
Django 1.5+ extending the user model:
https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#extending-the-existing-user-model