Django Filter Query Foreign Key - django

I'm struggling getting the right query for my project.
Here is an example or my model :
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __unicode__(self):
return self.name
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
def __unicode__(self):
return self.title
how do I get publisher from the book class for example I want to get all publisher for all books that have the title starting with 'hello'?

If you want to get Publishers, you have to start with Publisher. That means you have to query through the Book → Publisher relation backwards. Here's what the docs say about it:
Lookups that span relationships
To span a relationship, just use the field name of related fields across models, separated by double underscores, until you get to the field you want
...
To refer to a “reverse” relationship, just use the lowercase name of the model.
The query:
Publisher.objects.filter(book__title__startswith='hello')

Related

django many to one relationships

In the django document https://docs.djangoproject.com/en/3.2/topics/db/examples/many_to_one/, there are two tables, Report and Article,
class Reporter(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
def __str__(self):
return "%s %s" % (self.first_name, self.last_name)
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
def __str__(self):
return self.headline
class Meta:
ordering = ['headline']
My question, if you have a list of Reports, how would you get their articles? I've tried
articles = []
for report in reports:
article = Article.objects.filter(report = report)
articles.append(article )
but this does not give me all my data.
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE, related_name="articles")
Then you can just do reporter.articles.all()
Note: if your ForeignKey field doesn't have a related_name attribute, you can get the reverse relatioship by calling <model_name>_set. For example: reporter.article_set.all()

How to show foreign key field value instead of id in Django admin?

class Country(models.Model):
name = models.CharField(max_length=100)
code = models.CharField(max_length=100)
class Info(models.Model)
country_name = models.ForeignKey(Country, on_delete=models.CASCADE)
country_code = models.ForeignKey(Country, on_delete=models.CASCADE)
info = models.CharField(max_length=100)
In admin interface, while adding object in 'Info' model, 'country_name' field show IDs of countries by default. But I want to show names of countries instead of IDs.
And similarly, 'country_code' field of 'Info' model also show IDs of countries by default. But I want to show codes of countries instead of IDs.
How to do this?
Try this way:
The value you will return from __str__ that would be shown in admin.
class Country(models.Model):
name = models.CharField(max_length=100)
code = models.CharField(max_length=100)
def __str__(self):
return self.name
class Info(models.Model)
country_name = models.ForeignKey(Country, on_delete=models.CASCADE)
country_code = models.ForeignKey(Country, on_delete=models.CASCADE)
info = models.CharField(max_length=100)
def __str__(self):
return str(self.country_name.name)
Why are you using 2 fields for same result? Your model of Info should be:
class Info(models.Model)
country_name = models.ForeignKey(Country, on_delete=models.CASCADE)
info = models.CharField(max_length=100)
def __str__(self):
return str(self.country_name.code)

how to make dependent dropdown form in django

I have three models and every three models are dependent with each other.while adding the Studentfee model through form when I select the student name then the course price should appear only related to that student's course selection
models.py
from django.db import models
from django.db.models import CASCADE
class Course(models.Model):
title = models.CharField(max_length=250)
basic_price = models.CharField(max_length=100)
advanced_price = models.CharField(max_length=100)
basic_duration = models.CharField(max_length=50)
advanced_duration = models.CharField(max_length=50)
def __str__(self):
return self.title
class Student(models.Model):
name = models.CharField(max_length=100)
courses = models.ManyToManyField(Course)
address = models.CharField(max_length=200)
email = models.EmailField()
phone = models.CharField(max_length=15)
image = models.ImageField(upload_to='Students',blank=True)
joined_date = models.DateField()
def __str__(self):
return self.name
class StudentFee(models.Model):
student = models.ForeignKey(Student,on_delete=CASCADE)
total_fee = models.ForeignKey(Course,on_delete=CASCADE) # should dynamically generate in the form based on the selection of student.how ??
first_installment = models.IntegerField(blank=True)
second_installment = models.IntegerField(blank=True)
third_installment = models.IntegerField(blank=True)
remaining = models.IntegerField(blank=True)
def __str__(self):
return self.total_fee
I think you dealing with the problem about what should be computed and what should be stored.
I think you will need another model to manage this, something like
CourseSelection, and cost should be computed at the time of the payment and then stored as CourseSelectionPayment

How to filter django queryset with exclude?

Suppose I have the following models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
def __str__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
And I have Entry object e
How can I get all blogs that do not contain e?
How can I get all authors that are not associated with e?
How to exclude a queryset?
OK first this is how you would get the entry object and exclude e, I'll just assume e is the primary key. Then you can get all the authors except the ones related to e using the ORM, and then you could get all the blogs that have no mention of the e object using a related query which basically flips the foreign key.
exclude_e = Entry.objects.exclude(pk=e)
get_authors = exclude_e.authors.all()
get_blogs = exclude_e.blog_set.all()

Get associative table data from 2 level depths relationship in django using foreign keys

This is my problem that im trying to figure out being a beginner with django
I want to get the country in user app knowing that city table is connected to country table using foreign key. User table has city_id column. Please note that user already logged in. I get the city already but not the country
After that in my instructor app, i get that currency which is connected to country column currency_id.
This is what i have.
/instructors/model.py
from django.db import models
from locations.models import City, Country
class Class(models.Model):
...
city = models.ForeignKey(City, null=True, blank=True)
class Currency(models.Model):
name = models.CharField(max_length=20)
symbol = models.CharField(max_length=7, help_text="Code HTML")
initials = models.CharField(max_length=5, help_text="e.g. : CLP (Chilean Pesos)")
class Meta:
verbose_name_plural = "currencies"
def __unicode__(self):
return self.name
def get_label(self):
return '%s (%s)' % (self.symbol, self.initials)
/users/model.py
class User(AbstractUser):
...
city = models.ForeignKey(City, blank=True, null=True, db_index=True)
...
def get_locality(self):
locality = ''
if self.location:
locality = '%s, %s, %s' % (self.location.name, self.location.city.name, self.city.country.name)
elif self.city:
locality = '%s, %s' % (self.city.name, self.city.country.name)
return locality
/locations/model.py
from django.db import models
class Country(models.Model):
code = models.CharField(max_length=3)
name = models.CharField(max_length=100)
order = models.IntegerField(default=0)
currency_id = models.IntegerField(max_length=3)
class Meta:
verbose_name_plural = "countries"
def __unicode__(self):
return self.name
class City(models.Model):
country = models.ForeignKey(Country)
name = models.CharField(max_length=100)
order = models.IntegerField(default=0)
class Meta:
verbose_name_plural = "cities"
def __unicode__(self):
return "%s, %s" % (self.name, self.country)
class Location(models.Model):
city = models.ForeignKey(City)
name = models.CharField(max_length=100)
class Meta:
verbose_name_plural = "locations"
def __unicode__(self):
return "%s, %s" % (self.name, self.city)