Last object of foreign key in bulk - Django - python

I have two models:
class Author(models.Model):
name = models.CharField(max_length=30)
age = models.CharField(max_length=40)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author)
publication_date = models.DateField()
I need find last books of authors, who are 10 years old to list:
[(author1.name, book32.title), (author5.name, book75.title), ...]
I can do:
books = []
authors = Author.objects.filter(age=10)
books = [(a.name, a.book_set.last().title) for a in authors]
but it works too long.
How can i do that entirely by ORM and database?

You can use prefetch_related. It will not make a second query for the related items.
Author.objects.filter(age=10).prefetch_related('book_set')
On a side note, use an IntegerField instead for age (if you would be storing age in years only). It will be more efficient for such queries, and you would also be able to make queries to fetch all non-adult authors:
child_authors = Author.objects.filter(age__lt=18)

First, your age field should be an IntegerField:
age = models.IntegerField(max_length = 3)
and if you want the last, let's say, 3 books of each ten years author you can query like this:
ten_years_authors = Author.ojects.filter(age=10)
ten_years_authors_and_their_last_books = ten_year_authors.select_related('book_set')[:3]

Related

Django distinct selection

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

Django: Retrieving the number of objects after applying distinct() method

I have a course model which looks like:
class Course(models.Model):
course_code = models.CharField(max_length=20)
course_university = models.CharField(max_length=100)
course_instructor = models.CharField(max_length=100) # lastname
course_instructor_fn = models.CharField(max_length=100) # firstname
"""
More fields are here
"""
Now I have selected instructors for each university using:
qs = Course.objects.filter(course_university__iexact=uni).order_by('course_instructor','course_instructor_fn','course_university').distinct('course_instructor','course_instructor_fn','course_university')
My intention is to now count each the distinct course_code for each instructor using an aggregate Count() function:
so I am trying to basically do:
new_qs = Course.objects.filter(id__in=qs).annotate(course_count=Count('course_code', distinct=True).values_list('course_instructor_fn', 'course_instructor', 'course_count')
However, currently, I only get 1 for user_count no matter how many courses each instructor has.
My intention is to get the number of courses each instructor offers. How can I do this successfully?

Django getting information from three related tables. Joining tables

I have three tables that are related.
class Book(models.Model):
year_published = models.IntField()
author = models.ForeignKey(Author)
class Author(models.Model):
author_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
agent = models.ForeignKey(LitAgent)
class LitAgent(models.Model):
agent_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
Ok, I can get a LitAgent like so
getla = LitAgent.objects.get(agent_id=1)
I can get the authors like so
getauthors = Author.objects.filter(agent=getla.agent_id)
But how can I get all the books that an author has too and make sure the books line up to the right author? I also need access to the data in LitAgent and Author too
From my understanding, you want to get the books by using an agent_id. If this is what you want then you can accomplish this using
books = Book.objects.filter(author__agent__agent_id=1)
This will return a list of all books that the author related to the agent with id = 1. If you want to access the author for each book you can use
for book in books:
print book.author.name
# in order to print the author agent
print book.author.agent.name
On the other side you can reach the books from the LitAgent model.
Lets say
agent = LitAgent.objects.get(agent_id=1)
Then to get the authors it will be
authors = agent.author_set.all()
Now you can iterate
for author in authors:
for book in author.book_set.all()
print book

Copy or clone an object instance in Django/Python

I've following scenario:
class CourseTemplate(models.Model):
title = models.CharField(max_length=70)
teacher = models.ForeignKey(User)
description = models.TextField()
max_students = models.IntegerField()
sessions = models.ManyToManyField(CourseSession) # e.g. Session 1 Introduction, Session 2 Basics, etc.
rating = models.ManyToManyFields(StudentRating)
date_added = models.DateTimeField()
class CourseEnrollment(models.Model):
course = models.OneToOneField(CourseTemplate) # Each enrollment needs a new CourseTemplate Instance, so I can track it
students = models.ManyToManyField(User)
Class CourseSession(models.Model):
title = models.CharField(max_length=50)
date = models.DateTimeField()
details = models.CharField(max_length=100)
address = models.TextField()
#parent_course = models.ForeignKey(CourseTemplate)
class StudentRating(models.Model):
student = models.ForeignKey(User)
rating = models.IntegerField()
#course = models.ForeignKey(CourseTemplate)
Now a teacher (=User) can create a CourseTemplate with all the required details first. After it's saved, he can create a concrete "enrollment" for e.g. this semester with 5 sessions. Maybe he changes after 8 enrollments some details (e.g. CourseTemplate.description or the course now only has 7 sessions instead of 8).
I'd like to have a 1:1 relationship between each CourseTemplate instance and each CourseEnrollment, so I can see for example:
- Teacher X had 2012 three CourseEnrollments, two of them were the same or
- which rating has he received for his second course.
The presented "Template" should always be the "newest", so I'd just need to get the latest instance by CourseTemplate.date_added.
Does anyone know how I can avoid this problem?
Thanks a lot!
You can duplicate any existing django model instance by clearing its primary key, and then saving it again.
ct = CourseTemplate.objects.all()[0]
print ct.pk
# some original pk
ct.pk = None
ct.save()
print ct.pk
# will be a new auto-incremented

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