import data of models.py with 2 class into template - python

I am a amature django developer. I have a model with two class called "Post" and "Catagory". I want to read Category items in my template. How can I import my category in my template and show it's data in my page?
models.py
from django.db import models
from taggit.managers import TaggableManager
class Category(models.Model):
title = models.CharField(max_length=40)
def __unicode__(self):
return self.title
class Post (models.Model):
title = models.CharField(max_length=150)
body = models.TextField()
date = models.DateTimeField()
tags = TaggableManager ()
cats = models.ManyToManyField(Category)
def __unicode__ (self):
return self.title
Thank you.

If you are using class based views and want to list all categories you could do:
# urls.py
url(regex=r'^category/$',
view=CategoriesListView.as_view(),
name='category_list_all'),
# views.py
class CategoriesListView(ListView):
model = Category
# category_list.html
<h2>Category list</h2>
<ul>
{% for cat in category_list %}
<li>
{{ cat.category }}
</li>
{% endfor %}
</ul>
You would place the html file in <project_route>/<app_name>/templates/<app_name>/ or <project_route>/templates/<app_name>/
If you have an existing function based view that's working with the Post model then you can just do something like:
# views.py
...
post = get_object_or_404(Post, pk=pass_in_pk)
return render(request, 'post.html', {'post': post})
# post.html
<h2>Category list</h2>
<ul>
{% for category in post.cats %}
<li>{{ category.title }}</li>
{% endfor %}
</ul>
If you have a class based view based on a Post model using the DetailView then you can also use the above html, just place it in post_detail.html in the appropriate folder.

It`s like get the category value and assign into settings and passed into view html will work
def viewfuncion(request):
template_vars = {}
settings = Category.objects.get(pk=1)
template_vars['title_show'] = settings.title
t = loader.get_template('view.html')
c = Context(template_vars)
return HttpResponse(t.render(c), content_type = "application/xhtml")
So in your HTML { title_show } will print the content

Related

Django list class instances matching parent

I'm new to Django, so any help is appreciated. I have one class Gym and a second class Route (rock climbing gym and climbing routes). Each gym can contain multiple routes, but each route can only belong to one gym. I can list available gyms and click on one to go to the gym page, but I want to list all of the routes that belong to it and can't figure out how.
# /gym/models.py
from django.db import models
from django.shortcuts import reverse
class Gym(models.Model):
name = models.CharField(max_length=100)
image = models.ImageField(upload_to='gym', default='default_route.jpg')
address = models.CharField(max_length=200)
def get_absolute_url(self):
return reverse('gym:detail', kwargs={'pk': self.pk})
def __str__(self):
return self.name
# route/models.py
from django.db import models
from .utils import generate_qrcode
class Route(models.Model):
Gym = models.ForeignKey('gym.Gym', on_delete=models.CASCADE, null=True)
grade = models.CharField(max_length=10)
hold_color = models.CharField(max_length=20, default='')
rating = models.PositiveIntegerField()
date = models.DateTimeField(auto_now_add=True)
image = models.ImageField(upload_to='routes', default='default_route.jpg')
def __str__(self):
return str(self.pk)
# gym/views.py
from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView
from .models import Gym
from route.models import Route
def gym_list_view(request):
# Can filter this for specific gyms
qs = Gym.objects.all()
return render(request, 'gym/index.html', {'gym_list': qs})
def gym_detail_view(request, pk):
gym_obj = Gym.objects.get(pk=pk)
# This is where I don't know how to get the routes that belong to the current gym
routes_obj = Route.objects.get(pk=pk)
return render(request, 'gym/detail.html', {'gym_object': gym_obj, 'routes_obj': routes_obj})
# gym/templates/gym/detail.html
{% extends "base.html" %}
{% block title %}
{{ gym_object.pk }}
{% endblock title %}
{% block content %}
Gym ID: {{gym_object.pk }} <br><br>
<h3> {{ gym_object.name }} </h3>
{{ gym_object.address }}
<br><br>
<h4>Routes</h4>
route_obj: {{ routes_obj }}
{% endblock content %}
def gym_detail_view(request, pk):
gym_obj = Gym.objects.get(pk=pk)
# This is where I don't know how to get the routes that belong to the current gym
routes = gym_obj.route_set.all()
return render(request, 'gym/detail.html', {'gym_object': gym_obj, 'routes': routes})
Try this

django querysets in templates

I am trying to make specific queries by using some model entry fields.
I have the following model entry:
models.py
class Work(models.Model):
categories =(
('cat1', 'cat1'),
('cat2', 'cat2'),
('cat3', 'cat3'),
('cat4', 'cat4'),
('cat5', 'cat5'),
)
title = models.CharField(max_length=200)
description = RichTextUploadingField(config_name='awesome_ckeditor')
date = models.DateTimeField(default=timezone.now)
category = models.CharField(max_length=200, choices = categories, default = 'projects')
thumb = models.ImageField(upload_to = 'works/thumbs', blank = True)
content = models.FileField(upload_to = 'works/content_media', blank = True)
published = models.BooleanField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("work_detail",kwargs={'pk':self.pk})
#property
def thumb_url(self):
if self.thumb and hasattr(self.thumb, 'url'):
return self.thumb.url
#property
def content_url(self):
if self.content and hasattr(self.content, 'url'):
return self.content.url
here is the view:
views.py
class WorksListView(ListView):
template_name = 'template.html'
model = Work
def get_queryset(self):
return Work.objects.filter(published=True).order_by('-date')
and I am trying to query first by the category field then by entry in the following template:
template.html
{% for category in works_list.category %}
<ul data-category-name={{category.name}}>
{% for work in category.works %}
<li data-thumbnail-path={{thumbnail.url}} data-url={{content.url}} >
<div>
<p class="gallery1DecHeader">{{work.title}}</p>
<p class="gallery1DescP">{{work.description}}</p>
</div>
</li>
{% endfor %}
{% endfor %}
what do I need to change?
Okay, from what I can see there are a few problems. First, try adding context_object_name = 'works_list' That way you will be able to refer to the object_list as works_list like you do in the template outer for loop. The bigger problem is you are iterating over works_list.category, which according to your Work model is a Charlist(). I think you might be getting confused about what the choices kwarg does and expecting {% for category in works_list.category %} to iterate over your choices and giving you the list of cats you defined in categories. As far as I know, that's not how choices works.
If you go to your admin panel and add a new entry for your Work model, you'll see that category has a dropdown list that contains your list of cats. So, choices defines a set of legal category options for new Work objects, not a list in existing Work objects.
I think what you actually want is an additional model Category which defines: work = models.ForeignKey(Work, on_delete=models.CASCADE) as a one-to-many relationship. Basically, you want is for Work to have a subset of Category objects that you can iterate over. This will involve redesigning the way you structure and access your data though.
You need to change at least your views.py and template.html. Add a context_object_name and an extra context(Doc Link)
views.py
class WorksListView(ListView):
template_name = 'template.html'
model = Work
context_object_name = 'work_list'
def get_queryset(self):
return Work.objects.filter(published=True).order_by('-date')
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(WorksListView, self).get_context_data(**kwargs)
# Insert categories so that it can be used in template
context['categories'] = Work.categories
return context
template.html
{% for category in categories%}
<ul data-category-name={{category.0}}>
{% for work in work_list %}
{% if category.0 == work.category %}
<li data-thumbnail-path={{work.thumb_url}} data-url={{work.content_url}} >
<div>
<p class="gallery1DecHeader">{{work.title}}</p>
<p class="gallery1DescP">{{work.description}}</p>
</div>
</li>
{% endif %}
{% endfor %}
</ul>
{% endfor %}

show count and top_categories in the homepage

I want to show top_categories in the homepage. I have written top_categories function to list the categories that has most number of products. But I have written this function in Product Model. I am confused on where should I write this. Here is my code
class Category(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(max_length=50, unique=True)
class Product(models.Model):
name = models.CharField(max_length=200, unique=True,
blank=False, null=False)
categories = models.ManyToManyField(Category, related_name='products')
def top_categories(self):
product = Product.objects.values('id').annotate(
categories_count=models.Count('categories')).order_by('-categories_count')
return product
def home(request):
categories = Category.objects.all()
companies = Company.objects.all()[:12]
context = {
'categories': categories,
'companies': companies
}
return render(request, 'company/home.html', context)
Now there is a confusion, Do I have to implement top_categories function in Category modal or the way I am doing is fine? Because the job of showing the content in homepage is the role of home view.
You can do it in views.py
def home(request):
# arrange your category on basis of product_count
categories = Category.objects.annotate(product_count = Count('products')).order_by('-product_count')
# if you want only top 10 categories
# categories = categories[:10]
companies = Company.objects.all()[:12]
context = {
'categories': categories,
'companies': companies
}
return render(request, 'company/home.html', context)
In home.html
{% for category in categories %}
<h3> category name:</h3>{{category.name}}
<h3> Total product::</h3>{{category.product_count}}
{% endfor %}
Well think I would do something like this :
class Category(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(max_length=50, unique=True)
#staticmethod
def top_category():
return models.Count('categories')).order_by('-categories_count')
Made it a static method cause it's not about an instance. An even better way of doing it would be to extends the Category manager and add a method get_top_category to it so you can call a Category.objects.get_top_category(). Then just call it in your Product model :
def top_products(self):
count_category = Category.top_category() # or Category.objects.get_top_category() if you have done it this way
product = Product.objects.values('id').annotate(count_category)
return product
Some doc to override managers
I suggest you to using templatetags, because if you handle this case with views you will create similiar popular filter for another page.
# yourapp/templatetags/popcategories.py
from django import template
from yourapp.models import (Category, Product)
register = template.Library()
#register.assignment_tag
def popular_categories():
categories = Category.objects.all()
get_total = lambda c: Product.objects.filter(categories__slug=c.slug).count()
tags_list = [{'category': category, 'total': get_total(category)} for category in categories]
tags_list.sort(key=lambda x: int(x['total']), reverse=True)
return tags_list[:10] # return 10 top
And then, you can use it in your template company/home.html with;
{% load popcategories %}
{% popular_categories as categories_list %}
{% for category in categories_list %}
<a href="">
{{ category.name }} - {{ category.slug }}
</a>
{% empty %}
<p>No categories yet!</p>
{% endfor %}

How can I make categories in a image gallery in Django

Hi I'm a graphic designer and very new in programing, I've been learning Python for a while and wanna try something with Django, I'm making my website with Django just for fun and practice and I made this image gallery following some tutorials, but I want to add categorization to the images so in my website I can call some images by categorization and not showing up all the images at once. How can I do that?
MODELS.PY
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Photo(models.Model):
title = models.CharField(max_length = 200)
width = models.IntegerField(default = 0)
height = models.IntegerField(default = 0)
image = models.ImageField(null= False, blank = False, width_field="width", height_field="height")
timestamp = models.DateTimeField(auto_now_add = True, auto_now = False)
def __unicode__(self):
return self.title
class Meta:
ordering = ["-timestamp"]
VIEWS.PY
from django.shortcuts import render, redirect
from django.http import HttpResponse
from apps.photos.models import Photo
# Create your views here.
def photo_list(request):
queryset = Photo.objects.all()
context = {
"photos": queryset,
}
return render(request, 'photos/photos.html', context)
PHOTOS.HTML
{% extends 'base/base.html' %}
{% block contenido %}
<br>
<br>
{% for photo in photos %}
<h1>{{ photo.title }}</h1>
{% if photo.image %}
<img src="{{ photo.image.url }}" class="img-responsive">
{% endif %}
{% endfor %}
{% endblock %}
In your models you can add another field called something like
CHOICES = (
#('what_database_save', 'WHAT USER SEE'),
('cat1', 'category'),
('cat2', 'category2'),
)
category = models.Charfield(max_length, choices=CHOICES)
if you want you can add choices and later use it in your forms. In your views you can filter the photos by category using the queryset = Photo.objects.filter(category="cat1") method

django queryet to print product and it's models

my models are
class Product(models.Model):
name = models.CharField(max_length=50)
desc = models.CharField(max_length=50)
def __unicode__(self):
return self.name
class ProductModels(models.Model):
product = models.ForeignKey(Product)
name = models.CharField(max_length=50)
price = IntegerField(max_length=50)
def __unicode__(self):
return self.name
i can easily print in python , product and it's releated models , but in django template , i am unable to figure out how to print them .
I want data to be seen in html pages like this :
product1 modelpm1
modelpm2
product2 modelpm3
modelpm4
modelpm5
and so on .....
Of course I have created table and all the html related tags properly, but I am unable to figure out how to print this way in template.
Its the same in the template:
<ul>
{% for product in objects %}
<li>{{ product }}
<ul>
{% for product_model in product.productmodel_set.all %}
<li>{{ product_model }}</li>
{% endfor %}
</ul></li>
{% endfor %}
</ul>
Use the following view:
def product_list(request):
return render(request, 'template.html', {'objects': Product.objects.all()})
Or, if you prefer, use the generic views:
class ProductList(ListView):
template = 'template.html'
queryset = Product.objects.all()

Categories

Resources