django many to one relationships - django

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()

Related

Django Model, Multi value / Admin Area

I have start fresh with Django.
I am creating a blog and I need a hint now.
I want to add tags to my posts.
So I created a model for my tags:
class Tag(models.Model):
name = models.CharField(max_length=200, unique=True)
def __str__(self):
return self.name
This is my Post Model
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
What is the best way, that the user can select in the admin area tags for the post and more than one or create a new tag?
In the Post class, add a field ManyToMany
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
tag = models.ManyToManyField(Tag)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
You are looking for InlineModelAdmin particulary section regarding
Working with many-to-many models
something as following:
class TagInline(admin.TabularInline):
model = Post.tags.through
class PostAdmin(admin.ModelAdmin):
inlines = [
TagInline,
]
Also you are missing relationship on your model which should be ManyToMany
class Post(models.Model):
...
tags = models.ManyToManyField(Tag)

Django UNIQUE constraint

Django UNIQUE constraint failed error
django.db.utils.IntegrityError: UNIQUE constraint failed while I am using the unique together constraint in the models.
How can I use it properly?
While I am entering the data for the same publisher same issue same version number but different copy number I am getting the above error.
Is this the correct way to implement it??
class Book(models.Model):
publisher = models.IntegerField()
issue = models.CharField(max_length=255)
class Meta:
unique_together = ("publisher", "issue")
def __str__(self):
return "%s-%r" % (self.publisher,self.issue)
class Version(models.Model):
book = models.ForeignKey(Book, on_delete = models.CASCADE)
number = models.CharField(max_length=255)
book_name = models.CharField(max_length=255)
cover = models.ImageField(null=True)
description = models.CharField(max_length=255)
class Meta:
unique_together = ("book", "number")
def __str__(self):
return "%s %s" % (self.number, self.book)
class Copy(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, on_delete=models.CASCADE)
version = models.ForeignKey(Version, on_delete = models.CASCADE)
number = models.IntegerField()
book_id = models.AutoField(primary_key=True)
book_size = models.CharField(null=True, blank=True,max_length=255)
def __str__(self):
return "%r" % (self.book_id)
class Meta:
unique_together = ("version", "number")

Reference to another field in model.py // Django

I would like to return in str method of the Chapter, title of the Chapter and title of the Book (from book model). I need it for better display at the admin pages. How to do that?
Should I create some new method in Book or use Model instance reference https://docs.djangoproject.com/en/1.11/ref/models/instances/#model-instance-methods ?
Or maybe I should use Retrieving specific objects with filters?
https://docs.djangoproject.com/en/1.11/topics/db/queries/#retrieving-objects
I am new to the django, thank you in advance for the solutions.
class Book(models.Model):
author = models.CharField(max_length=200)
title = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
def __str__(self):
return self.title+" ("+self.author+")"
def book_author(self):
return self.author
class Chapter(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
title = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
body = models.TextField()
hierarchy = models.IntegerField()
sort = models.IntegerField(unique=True)
def __str__(self):
print(repr(Book))
print(repr(Book.author))
# print(repr(Book.objects.all().filter(id==1)))
# print(repr(Book.objects.get(id=1)))
print(repr(Book.book_author(self)))
return self.title+"(book: "+")"
def __str__(self):
return '%s (%s)' % (self.title, self.book.title,)
To print your object data in admin panel more nicely you should overide __str__ method for your models.
For example your code should look like:
class Book(models.Model):
author = models.CharField(max_length=200)
title = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
def __str__(self):
return 'Book with title: {} writen by {}'.format(self.title, self.author)
`

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)

Django Filter Query Foreign Key

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')