Django many-to-many - python

class Actor(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Movie(models.Model):
title = models.CharField(max_length=50)
actors = models.ManyToManyField(Actor)
def __str__(self):
return self.title
how can I access to the movies of an actor from Actor object in a template ?
I need to do it in both directions.
This worked from movies to actors.
{{movie.actors.all}}

just put related_name into actors field
actors = models.ManyToManyField(Actor, related_name="actor_movies")
and then in template:
{{ actor.actor_movies.all }}
or if you dont want related_name:
template:
{{ actor.movie_set.all }}

Related

Django ForeignKey attribute is not showing up in HTML

I have some models and connected each other. And in my views I get the Chapter model ordered by date published, and then remove the ones with same Manga (foreign key associated with other model).
But apparently accept for the fields is not connected with anything, and I can't access the models fields. But also because I am working with a query set I can't sort by id or anything. Also, I have to access the Manga models fields associated with chapter. But it does not show up in the HTML. How can I do it?
My models:
class Manga(models.Model):
manga_name = models.CharField(max_length=255, default="null")
manga_image = models.ImageField(upload_to="thumbnail", default="thumbnail/noimage.png")
manga_views = models.IntegerField(default=0)
def __str__(self):
return f"{self.id}, {self.manga_name}"
class Fansub(models.Model):
fansub_name = models.CharField(max_length=255, default="null")
def __str__(self):
return f"{self.id}, {self.fansub_name}"
class Chapter(models.Model):
chapter_number = models.IntegerField(default=0)
chapter_url = models.URLField(default="www.example.com")
manga = models.ForeignKey(Manga, on_delete=models.CASCADE)
fansub = models.ForeignKey(Fansub, on_delete=models.CASCADE)
relase_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.chapter_number}, {self.manga}, {self.fansub}"
My view:
def Index(request):
manga = Manga.objects.all()
chapter = Chapter.objects.all().values()
fansub = Fansub.objects.all().values()
mostview = manga.order_by("-manga_views")[:5]
relasedateorder = chapter.order_by("relase_date")
context = {
"Manga": manga,
"Chapter": chapter,
"Fansub": fansub,
"Mostview": mostview,
"LastUpdated": relasedateorder,
}
template = loader.get_template("Index.html")
And finally the HTML:
{%for d in LastUpdated%}
<p>{{d.manga}}</p>
{%endfor%}
You can access the all the instances of Manga model associated with chapter instance by using _set as suffix in the following way:
{% for i in LastUpdated %}
<p>{{i.chapter_number}}</p>
<h2> manga model attributes below</h2>
{% for j in i.manga_set.all %}
{{j.manga_name}}
{{j.manga_views}}
{% endfor %}
{% endfor %}
Also you should use Chapter.objects.all().order_by("relase_date") this queryset as using .values() gives you a key-value pair (dict).

How to pass multiple values from models.py to HTML via views.py in Django

I have a following models.py for my Django blog, I made a following views.py to pass the value of the slug for my URL parameter.
However I am struggling to create a model in views to get other data(person & description) from Category class.
I have tried some patterns by myself but can not pass them to HTML. (always Error or not showing)
Can you please give me some idea of how to solve this.
models.py
class Category(models.Model):
person = models.CharField(max_length=20)
description = models.TextField()
slug = models.SlugField()
def __str__(self):
return self.person
views.py
def blog_category(request, category):
posts = Post.objects.filter(categories__slug__contains=category).order_by("-created_on").distinct()
context = {"category": category, "posts": posts}
return render(request, "blog_category.html", context)
HTML(Localhost:8000/slug)
{{ person }}
{{ description }}
this is full code of my models.py
class Category(models.Model):
person = models.CharField(max_length=20)
description = models.TextField()
slug = models.SlugField()
def __str__(self):
return self.person
class Recommender(models.Model):
recommender_name = models.CharField(max_length=20)
slug = models.SlugField()
def __str__(self):
return self.recommender_name
class Post(models.Model):
book_title = models.CharField(max_length=255)
author = models.CharField(max_length=255)
book_link = models.CharField(max_length=255)
recommenders = models.ForeignKey("Recommender", on_delete=models.CASCADE,)
source = models.TextField()
source_link = models.CharField(max_length=255)
created_on = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
categories = models.ManyToManyField("Category", related_name="posts")
slug = models.SlugField()
def __str__(self):
return self.book_title
posts = Post.objects.filter(categories__slug__contains=category).order_by("-created_on").distinct()
Is going to return a queryset. It can have more than one instance of the model class (since you are using filter). In your context you are sending this queryset as posts to your templates.
So in your HTML you can use something like this. You need to use a for loop since there can be more than one item in posts.
{% for post in posts %}
{% for category in post.categories.all %}
{{ category.person }}
{{ category.description }}
{% endfor %}
{% endfor %}
I would look at this example.
Namely, if you render the template like it is shown in the example, you should be able to do
{{ category.person }} {{ category.description }}

Displaying objects by categories in Django

I'm building an ecommerce app and I'd like to make a section that shows some featured items by category. I'm using three sliders that display those items; Each slider is a featured category and each item in the slider is a featured item.
The problem is that I can't figure out how to assign the item to the proper slider. For example: I want to assign a JeansJacket to "Clothes and accesories" and display it. I tried this:
{% for cat in categories %}
<h1>{{ cat.cat_name }}</h1>
<!--(carousel code in between)-->
<div class="carousel-inner" role="listbox">
{% for item in featured_items %}
{% if item.Categoría in cat.cat_name %}
{{ item }}
{% endif %}
This is a simplified version of what I have, without the rest of the content. I just can't figure out how to iterate though the featured items and display them in the corresponding category.
Edit: This is in models.py:
class Categorías(models.Model):
cat_name = models.CharField(max_length=30)
Destacado = models.BooleanField()
class Meta:
ordering = ('cat_name',)
verbose_name = 'Categoría'
verbose_name_plural = 'Categorías'
def __str__(self):
return self.cat_name
class publicaciones(models.Model):
Título = models.CharField(max_length=30)
Descripción = models.TextField(max_length=200)
Precio = models.FloatField()
Fotos = models.ImageField()
Categoría = models.ForeignKey(Categorías, on_delete=models.CASCADE)
Promocionado = models.BooleanField()
class Meta:
verbose_name = 'Publicación'
verbose_name_plural = 'Publicaciones'
def __str__(self):
return self.Título
You can use prefetch_related and Prefetch with a custom query to get all related articles for each category.
categories = Categorías.objects.prefetch_related(Prefetch(
'publicaciones_set',
queryset=publicaciones.objects.filter(Promocionado=True),
to_attr='featured_items'
))
Now you can loop over each category and then loop over this prefetch. You don't need to create a separate featured_items queryset
for category in categories:
for featured_item in category.featured_items:
...
You can use apply this pattern to your template

How can I display content in a model object in template?

How can I display country, and city of an UserType1 object in template?
class UserType1(models.Model):
user=models.OneToOneField(User,parent_link=True,primary_key=True)
country = models.CharField(max_length=50)
city = models.CharField(max_length=50)
def __str__(self):
return str(self.user)
def get_country(self):
return self.country
def get_city(self):
return self.city
I have the below in views.py
def profile(request,userid):
basic_info = User.objects.get(pk=int(userid))
profile = UserType1.objects.filter(user=int(userid))
template_name = 'users/profile.html'
return render(request, template_name, {'userid':userid,'basic_info':basic_info, 'profile':profile})
and the following in template
{% if profile %}
{{ profile.get_city }}
{{ profile.city }}
{% endif %}
Neither worked. Thanks!
It looks like you are accessing properties on a queryset, rather than a model instance, as you haven't called get on UserType1.
Try:
profile = UserType1.objects.get(user=int(userid))
As an aside though, a small change would simplify your code a little:
user = models.OneToOneField(User, parent_link=True, primary_key=True, related_name='profile')
...
basic_info = User.objects.get(pk=int(userid))
profile = basic_info.profile

Requests for django in the case of a foreign key

I have two tables, Author and Book, Each book is written by a mutliple author, by against an author can create a (one) book, I want to get the book list created by a single author.
In my template, I would view the authors who have written one book
my models.py
class Book(models.Model):
user = models.OneToOneField(User,related_name='user')
name = models.CharField(default=0)
def __unicode__(self):
return u'%s' % self.user
class author(models.Model):
name_auth = models.CharField(max_length=256)
Book = models.ForeignKey(compte)
def __unicode__(self):
return u'%s' % (self.name_auth)
my view.py
Book1 =Book.objects.filter(user=request.user).values()
Book1_id= Book1.id
author = Author.objects.filter(pk=Book1_id).values
reponse[author]=author
my template
{% for t in author %}
<td>{{ t.name }}</td>
{% endfor %}
The logic in your models is incorrect given your statement...
"A book can have multiple authors"
You need to use a ManyToManyField to represent the authors of a book:
class Author(models.Model):
user = models.OneToOneField(User)
def __unicode__(self):
return self.user.get_full_name()
class Book(models.Model):
authors = models.ManyToManyField(Author)
name = models.CharField(max_length=500)
def __unicode__(self):
return self.name
# views
from django.shortcuts import render, get_object_or_404
def book_detail(request, book_id):
book = get_object_or_404(Book, id=book_id).prefetch_related('authors')
return render(request, 'book_detail.html', {'book': book})
# book_detail.html
{% for author in book.authors.all %}
{{ author }}
{% endfor %}

Categories

Resources