Employee class has id, first_name, last_name, and a lot more fields.
I want to select all the employees that do not have the same last_name, It's something like distinct in SQL, how to do that?
employees = Employee.objects.value('last_name').distinct() will only include the last_name, so I cannot find id.
If I do employees = Employee.objects.value('id', 'last_name').distinct() the results.count() looks different.
That's just because you may have employees with the same last name.
When you add 'id' in the query, you ask for all distincts rows based on the two criterias, and you always have distinct id.
Am I clear ?...
Related
I have following tables:
User: userid, username
Customer: customerid, customer name, userid
Sales: salesid, customerid, userid
User filters sales and customers. And also User and customer should be able to filter sales.
How to make a star schema of the above?
Is it correct to duplicate the customer table such that 1 is a dim and other is fact?
Should the both customer tables link to each other or not have Link?
I have a table called user_info. I want to get names of all the users. So the table has a field called name. So in sql I do something like
SELECT distinct(name) from user_info
But I am not able to figure out how to do the same in django. Usually if I already have certain value known, then I can do something like below.
user_info.objects.filter(name='Alex')
And then get the information for that particular user.
But in this case for the given table, I want to get all the name values using django ORM just like I do in sql.
Here is my django model
class user_info(models.Model):
name = models.CharField(max_length=255)
priority = models.CharField(max_length=1)
org = models.CharField(max_length=20)
How can I do this in django?
You can use values_list.
user_info.objects.values_list('name', flat=True).distinct()
Note, in Python classes are usually defined in InitialCaps: your model should be UserInfo.
You can use values_list() as given in Daniel's answer, which will provide you your data in a list containing the values in the field. Or you can also use, values() like this:
user_info.object.values('name')
which will return you a queryset containing a dictionary. values_list() and values() are used to select the columns in a table.
Adding on to the accepted answer, if the field is a foreign key the id values(numerical) are returned in the queryset. Hence if you are expecting other kinds of values defined in the model of which the foreign key is part then you have to modify the query like this:
`Post.objects.values_list('author__username')`
Post is a model class having author as a foreign key field which in turn has its username field:
Here, "author" field was appended with double undersocre followed by the field "name", otherwise primary key of the model will be returned in queryset. I assume this was #Carlo's doubt in accepted answer.
I would like with an unique field, to obtain the name of the model where it belongs. I was trying to use the get_model but it has another purpose.
Suppose that you have a school with multiple classrooms (each classroom is a model), and you wan to search a student with just the ID of him, receiving the name of the classroom where the student is.
So you type the ID (primary key) and the function will return you the class (model) where the student belong
I would like with an unique field, to obtain the name of the model where it belongs.
To get the model, to which a field belongs, you can use the model attribute:
Returns the model on which the field is defined. If a field is defined
on a superclass of a model, model will refer to the superclass, not
the class of the instance.
The above will answer your question, but a bigger issue is with this:
Suppose that you have a school with multiple classrooms (each
classroom is a model), and you wan to search a student with just the
ID of him, receiving the name of the classroom where the student is.
This is not a sustainable model and will cause issues as each classroom means a new table. This structure will cause you problems when you are doing searches across classrooms.
The second issue is you are confusing the value of a field with the name of the field. A primary key (the id) is a value. You can search for values if you know what field there are in, if you want to retrieve a record with primary key value 1, you would write a query like this:
SELECT * FROM classroom_table WHERE id = 1
In Django, this is Classroom.objects.get(id=1)
You can't go the other way around, that is "find me the table, that has the value "1" in the field of id" which is what you are asking to do here.
You need to fix your database structure so that there is one model for students, and one model for classroom; and a student can belong to many classrooms:
class Student(models.Model):
name = models.CharField(max_length=200)
class Classroom(models.Model):
students = models.ManyToMany(Student)
Now you can do things like find all classrooms for a student with id 1:
student = Student.objects.get(id=1)
for room in student.classroom_set.all():
print(room)
This question isn't very clear.
If you have a Student model and a Classroom model, and there is a ForeignKey from Student to Classroom, then you need to get the student from the primary key:
student = Student.objects.get(pk=my_pk_value)
and then get its classroom:
student.classroom
I have a list of employers, each of which have multiple contacts. One of those contacts may have been designated as primary for that organization.
class Employer(models.Model):
pass
class EmployerContact(models.Model):
employer = models.ForeignKey(Employer)
primary = models.BooleanField(default=False)
I need to display a list of employers and their primary contacts.
If I use Employer.objects.all(), I get all of them but then need an extra query to get the primary contact per employer, on a long list, this is not very efficient.
If I select on primary contacts and .select_related('employer') I get all the employers that have primary contacts, but miss those that don't have any contact (or maybe a primary contact has not yet been selected).
How can I get the list of Employers with their primary contact efficiently without missing employers with no primary contact?
Is there someway using .extra maybe?
You could use prefetch_related (which allows you to cache relationships that select_related can't) to first fetch and cache the related EmployeeContact objects, and then do the logic for finding if they have primary=True or not in python.
This would do it in two queries:
employees = Employee.objects.all().prefetch_related("employeecontact_set")
l = []
for e in employees:
for c in e.employeecontact_set.all():
if c.primary:
l.append(e.pk)
employees = employees.filter(pk__in=l)
I have a Project model similar to:
class Project(models.Model):
...
lead_analyst=models.ForeignKey(User, related_name='lead_analyst')
...
I want to use django aggregation to return all users with a count of projects per user. Something like:
models.User.objects.annotate(project_count=Count('project_set'))
Only that doesn't work because the auth.user has no knowledge about my Project class. I get the error:
Cannot resolve keyword 'project_set' into field. Choices are: date_joined, email, employee, first_name, groups, id, is_active, is_staff, is_superuser, last_login, last_name, lead_analyst, logentry, message, password, siteprofile, submitter, user_permissions, username
Two part question, really:
How to obtain this count of Projects per auth.user
Is there a better way to write the association between my Project class and the auth.user class that would make this aggregation viable?
Or should I just break into raw sql for aggregations (either via raw sql in django or a view in the database)?
Nothing wrong with your models - that's exactly how to set up that relation. The problem is simply that you've specified a related_name in the foreignkey, so as far as User is concerned, there's no project_set - there's a lead_analyst instead. In fact you can see this in the list of fields given by your error message.
So your aggregate query should read:
models.User.objects.annotate(project_count=Count('lead_analyst'))
(I must say, I think you've chosen a misleading related name here - you would be better off sticking to the default, in which case your original syntax would have worked.)