Django distinct selection - python

i have this model:
class Person:
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
sexe = models.TextChoices('M', 'F')
arrival_date = models.DateField(max_length=30)
reason = models.CharField(max_length=30)
It turns out that the same person can be registered several times (only the arrival date and the reason change).
I would like to make a query that lists distinctly persons. For example, if a person is registered many times, he will be selected only once.
How can i do it ? Thanks.

you can get data in this way:
Person.objects.values_list('first_name', 'last_name', 'sexe').distinct()

for mysql
Person.objects.filter(positive = 1).order_by().values('first_name').distinct()
for Postgre:
Person.objects.order_by('first_name').distinct('first_name')
Documentation Here

Related

How to use values and distinct on different field on Django ORM?

currently I have terms on my applications and one user can have a lot of terms registered, and my current model is like this
class Term(models.Model):
id = models.UUIDField("id", default=uuid.uuid4, editable=False, primary_key=True)
user_id = models.PositiveIntegerField("user id", default=None)
name = models.CharField()
sometimes I need to do a query to get all the users who have terms registered, so I do the following query:
Term.objects.filter(active=True)
.order_by("user_id")
.values("user_id")
.distinct()
and this is enough to solve my problems, but now I'll change my model and it will look like this:
class Term(models.Model):
id = models.UUIDField("id", default=uuid.uuid4, editable=False, primary_key=True)
user_id = models.PositiveIntegerField("user id", default=None)
name = models.CharField()
shared_with = ArrayField(models.PositiveIntegerField("id do usuario"), blank=True) # New
How you can see, I've added a new field named shared_with, that basically is a array of user ids which I want to share terms, So now I need to make a query who will return all ids who can have terms registered (shared_with included). So if i register a Term with user_id = 1 and shared_with = [2,3], my query need to return [1,2,3].
I've solved this problem today with the following code, but I think I can do this just using django ORM and one query:
users = set()
for user in (
Term.objects.filter(active=True)
.order_by("user_id")
.values("user_id")
.distinct()
):
users.add(user["user_id"])
for user in (
Term.objects.filter(active=True)
.order_by("user_id")
.values("shared_with")
):
for user_id in user["shared_with"]:
users.add(user_id)
print(users) # {1,2,3}
If someone knows how to do it and can share the knowledge, I will be grateful.
I don't recommend using the PositiveIntegerField and ArrayField as relations between tables, you can use ForeignKey and ManyToManyField instead, in your case what I understand is a user can have many Terms and a Term can be shared among many users, so the perfect solution is to add ManyToManyField in your User model
class User(AbstarctUser):
... (your fields)
terms = models.ManyToManyField(Term, related_name="users")
and Term model will be like:
class Term(models.Model):
id = models.UUIDField("id", default=uuid.uuid4, editable=False, primary_key=True)
name = models.CharField(max_length=200)
active = models.BooleanField(default=True)
... (other fields)
in that case, if you want to extract user ids with active terms, you can get it as following :
users = User.objects.filter(terms__active=True).distinct().values_list("id", flat=True)

Django chain multiple queries in view

I have three models:
Course
Assignment
Term
A course has a ManyToManyField which accesses Django's default User in a field called student, and a ForeignKey with term
An assignment has a ForeignKey with course
Here's the related models:
class Assignment(models.Model):
title = models.CharField(max_length=128, unique=True)
points = models.IntegerField(default=0, blank=True)
description = models.TextField(blank=True)
date_due = models.DateField(blank=True)
time_due = models.TimeField(blank=True)
course = models.ForeignKey(Course)
class Course(models.Model):
subject = models.CharField(max_length=3)
number = models.CharField(max_length=3)
section = models.CharField(max_length=3)
professor = models.ForeignKey("auth.User", limit_choices_to={'groups__name': "Faculty"}, related_name="faculty_profile")
term = models.ForeignKey(Term)
students = models.ManyToManyField("auth.User", limit_choices_to={'groups__name': "Student"}, related_name="student_profile")
When a user logs in to the page, I would like to show them something like this bootstrap collapse card where I can display each term and the corresponding classes with which the student is enrolled.
I am able to access all of the courses in which the student is enrolled, I'm just having difficulty with figuring out the query to select the terms. I've tried using 'select_related' with no luck although I may be using it incorrectly. So far I've got course_list = Course.objects.filter(students = request.user).select_related('term'). Is there a way to acquire all of the terms and their corresponding courses so that I can display them in the way I'd like? If not, should I be modeling my database in a different way?
https://docs.djangoproject.com/en/1.11/ref/models/querysets/#values
You could use values or values_list here to get the fields of the related model Term.
For example expanding on your current request:
To retrieve all the Terms' name and duration for the Courses in your queryset
Course.objects.filter(students = request.user).values('term__name', 'term__duration')
I am not sure what the fields are of your Term model, but you would replace name or duration with whichever you are trying to get at.
I think it helps you
terms = Terms.objects.filter(....) # terms
cources0 = terms[0].course_set.all() # courses for terms[0]
cources0 = terms[0].course_set.filter(students=request.user) # courses for terms[0] for user

Python get GenericRelation objects

I have the following code:
data/telephone.py:
class TelephoneNumber(models.Model):
MOBILE = 0
HOME = 1
TELEFON_CHOICES = (
(MOBILE, _("Mobile")),
(HOME, _("Landline")),
)
object_id = models.PositiveIntegerField()
content_type = models.ForeignKey(ContentType)
of = generic.GenericForeignKey('content_type', 'object_id' )
label = models.SmallIntegerField(choices=TELEFON_CHOICES)
number = models.CharField(max_length=20, blank=True)
model.py:
class Staff(models.Model):
user = models.OneToOneField(User)
telephonenumbers = GenericRelation(TelephoneNumber, related_query_name='telnumber')
No I want to provide a function to retrieve every telephone number of a user like this:
def get_telnumbers(self):
tellist = []
#print(self.telephonenumbers.all())
for tel in self.telephonenumbers.all():
tellist.append(tel)
return tellist
The problem is, that the line print(self.telephonenumbers.all()) does not print any telephonenumbers, even though a lot have been provided.
The returned dict is empty as well.
How can I access the GenericRelation objects saved within the Staff context?
Edit:
The following code:
for tel in TelephoneNumber.objects.all():
print(tel)
print(tel.of)
gives me every telephone number saved, and through tel.of the right staff user which the telephone number belongs to.
So why isn't self.telephonenumbers.all() working (self.user also returns the right user for which the telephone number should have been saved)?
Make sure that when creating a new TelephoneNumber object you provide content_object attribute to be the corresponding Staff object
I am still not sure why self.telephonenumbers.all() is not working.
But I am using this (kind of ugly) workaround now:
def get_telnumbers(self):
for tel in TelephoneNumber.objects.all():
if tel.of.id == self.id:
...
If someone still has a better idea, I am open to that!

Get all teachers that have at least 1 subject on table - Django Query Set

I Would like to get all the Teachers that have at least 1 subject. Currently I'm using...
user = users.objects.all().order_by('-karma')[:100]
Because people who does not have any subjects related is a Student.
Here is my models.py
class subjects(models.Model):
id_user = models.IntegerField(db_column='ID_user') # Field name made lowercase.
s = models.CharField(max_length=90)
def __unicode__(self):
return self.s
class Meta:
db_table = 'subjects'
class users(models.Model):
email = models.EmailField(max_length=160)
nick = models.CharField(unique=True, max_length=60)
karma = models.IntegerField(max_length=11)
pass_field = models.CharField(db_column='pass', max_length=160)
One option is to do this in two steps:
get id_user list from subjects model with the help of values_list():
user_ids = subjects.objects.values_list('id_user', flat=True).distinct()
get all users by the list of id_users using __in:
print users.objects.filter(pk__in=user_ids)
Also, since models are not related, you can make a raw query that would do the same in one go.

Filtering a QuerySet With another QuerySet

Hi i'm not very good at English but i'll try to explain myself the best i could. I'm using python and Django to create a web project.
I have this 4 models (this is the best translation i can do of the tables and fields):
class Humans (models.Model):
name = models.CharField(max_length=15)
surname = models.CharField(max_length=15)
doc_num = models.CharField(max_length=11)
...
class Records (models.Model):
closing_state = models.CharField(max_length=2)
...
humans = models.ManyToManyField(Humans, through='Reco_Huma')
class Reco_Huma (models.Model):
id_record = models.ForeignKey(Records)
id_human = models.ForeignKey(Humans)
categorys = models.CharField(max_length=2)
reserv_identity = models.CharField(max_length=2)
repre_entity = models.CharField(max_length=2)
class Observations (models.Model):
id_record = models.ForeignKey(Records)
text = models.CharField(max_length=80)
category = models.CharField(max_length=2, choices=CAT)
Now given a doc_num from Humans, a text from Observations i want to get a QuerySet Of all the Records.
To clarify i first do this:
q1 = Reco_Huma.objects.filter(id_human.doc_num=x)
q2 = Observations.objects.filter(text=y)
both query-sets give me a list of id_record and then i want to connive that lists and filter the Records table with that id_record's
I hope you can understand me
Thanks in advance
To rephrase your query, you want all the Records associated with a certain Human and which have a certain Observation. So it should be:
result = Records.objects.filter(observations__text=y, humans__doc_num=x)
As a general rule, if you want to end up with a certain type of object, it helps to start from there in your query.

Categories