django how to display number of items - django

I was wondering how I do count the number of poll in my question model using set_count
and I also want to display it in a template please show me using the code thanks
class Question(models.Model):
question_text = models.CharField(max_length=10)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
title = models.CharField(max_length=10)
site_url = models.URLField()
website_type = models.CharField(max_length=100)
budget = models.CharField(max_length=100)
duration = models.CharField(max_length=100)
description = models.TextField()
I want the show the total of question

This is what you write in your views.py:
First, to count it, you have to import the model itself
If models.py and views.py both belong to same app:
from .models import Question
If they belong to different apps:
from <appname>.models import Question
I'll assume they belong to the same app, in views.py:
from django.shortcuts import render
from .models import Question
def index(request):
number_of_questions = Question.objects.count()
context = {
'number_of_questions':number_of_questions,
}
return render(request, '<appname>/index.hmtl>', context)
On the first line of the function it just counts the number of questions with .count() method which comes with django. On the second line we define context that we want to use in template, in this case 'number_of_questions':number_of_questions, so in the html template to display this number we'll use {{ number_of_question }}, have we defined it like so: 'questions':number_of_questions, then in the template we would use {{ questions }}, the end result will be that it shows number_of_questions.
In index.html (Or whatever you named the template):
<p>number of questions:</p>
<p>{{ number_of_questions }}
If you have trouble understanding anything I suggest you read through these:
Django documentation on templating
Some information about python dictionaries
EDIT:
I also highly recommend reading this:
Django documentation about making queries to the database

Related

Is there a way to automate creation of pages(and slugs) as and when a record is created in Django

I'm trying to make a Django website which has all products with all their details(each product has it's own page). However, since there are too many products and they keep changing, I want to automate the creation and deletion of pages according to the database model (models.py).
Am I supposed to use a class based view? Am I supposed to use a function based view with a loop in it?
# models.py
import uuid
from django.db import models
class Brand(models.Model):
brand_id = models.AutoField(primary_key=True, unique=True)
brand_name = models.CharField(max_length=100, unique=True)
class Product(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=100, null=False, blank=False)
brand_id = models.ForeignKey(Brand)
# A lot more columns will follow (didn't lock on them yet)
# This is what I had thought of initially
If I understand what you are trying to do (create product pages automatically), you can override the save method in your Products model to create a new Page each time a Product is added, and then use models.CASCADE in the foreign key so that if a product is deleted, the associated page is deleted, like so:
from django.utils.text import slugify
class Page(models.Model):
product = models.ForeignKey('Product', on_delete=models.CASCADE)
...
class Product(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(blank=True, null=True)
...
def save(self, *args, **kwargs):
self.slug = slugify(instance.name)
page = Page.objects.create(product=self,...)
page.save()
super(GeeksModel, self).save(*args, **kwargs)
You can also use Django signals, like so in your models.py file:
#receiver(post_save, sender=Product)
def create_product_page(sender, instance, created, **kwargs):
if created:
instance.slug = slugify(instance.name)
page = Page.objects.create(product=instance,...)
page.save()
instance.save()
In your views.py, for example, to get a page:
def product_page(request, product_id, product_slug):
page = Page.objects.get(product__id=product_id)
...
context = {
'page_data': page
}
return render(request, 'page_template.html', context)
And in your urls.py for the custom product pages:
...
path('/products/pages/<int:product_id>/<str:product_slug>/', product_page, name="product_page")
...
So the url would look like:
http://example.com/products/pages/3/my-amazing-widget/
If you created the link dynamically in a template with something like:
{% for product in products %}
<p><a href='{% url 'product_page' product.id product.slug %}'>{{ product.name }}</a></p>
{% endfor %}
And there are other ways as well. In the model example above, I included a SlugField you can use to generate the custom URL as well. If you elaborate on your question I can update my answer.

What is the most efficient way to make Post previews on Django?

I am making a Blog where I want for the home page to show only the first 100 characters of each post.
My point is to make better use of space. If a person want to read a post, that person can just click to read it.
I have some ideas on how to do it, but I think they won`t work or are inefficient:
To create a subclass on blog models.py where I would inherit the Post class, save the first hundred characters of each content to a list and make a loop to save each list on the database;
To place a instruction on blog views.py 'FirstPageView' class where it would only exhibit the first hundred characters.
The 'Post' and 'FirstPageView' mentioned classes are as follows:
on 'blog/views.py':
from django.views.generic import ListView
class FirstPageView(ListView):
model = Post
template_name = 'Blog/home.html'
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 6
on 'blog/models.py':
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, models.SET_NULL, blank=True, null=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
So what would be the most efficient way to make those previews?
You can use built-in template tags:
{{ posts.content|truncatechars:100 }}

Correctly returning object through Many to Many relationship

My objective is to display a readable list of Articles that belong to my user named 'Admin'
In other words, give me all articles that Admin owns. In my sample data I have Admin owning 1 article.
Problem: When I return the object, its a completely unreadable and unhelpful representation of this object. I'm thinking of adding a unicode() method to my model here but I don't know how!!
Model.py:
from django.db import models
from django.contrib.auth.models import User
class Article (models.Model):
question = models.CharField(max_length=255, unique=True, blank=False)
keywords = models.TextField(max_length=500, blank=True, null=True)
def __unicode__(self):
return self.question
class ArticleUserOwnership (models.Model):
article = models.ManyToManyField(Article)
user = models.ManyToManyField(User)
-- you can see here I'm hooking into the admin user table
Views.py:
from django.http import HttpResponse
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from GeorgiaArticleManager.models import Article, ArticleUserOwnership
from django.shortcuts import render
def myarticles(request):
if request.user.is_authenticated():
# articles of admin with id= 1
my_articles = ArticleUserOwnership.objects.filter(user=1)
context = {'my_articles': my_articles}
return render(request, 'template/myview.html', context)
myview.html:
ul
{% for ArticleUserOwnership in my_articles %}
li{{ ArticleUserOwnership }}/li
{% endfor %}
/ul
In summary of above:
ArticleUserOwnership.objects.filter(user=1) returns me an object that when I display it on myview.html, I just get 'ArticleUserOwnership object'. I'm sure this is the correct returned object but, I'd like to see returned Article.question. For example Admin owns 'test title 1' and I'd like to see this article question field displayed properly.
my_articles = ArticleUserOwnership.objects.filter(user=1)
gives you a list of ArticleUserOwnership instances. If you want of list of articles try this instead:
auo = ArticleUserOwnership.objects.get(user=1) # could raise DoesNotExist
my_articles = auo.article.all() # you should rename this field 'articles'
However, that ArticleUserOwnership model doesn't really make sense, my guess is that what you're really trying to do is this:
from django.db import models
from django.contrib.auth.models import User
class Article (models.Model):
question = models.CharField(max_length=255, unique=True, blank=False)
keywords = models.TextField(max_length=500, blank=True, null=True)
owners = models.ManyToManyField(User, related_name='owned_articles')
def __unicode__(self):
return self.question
You would then access your data like so:
my_articles = user.owned_articles.all()
See the documentation for examples of how to use ManyToManyFields.
try this:
class ArticleUserOwnership (models.Model):
article = models.ManyToManyField(Article)
user = models.ManyToManyField(User)
def __unicode__(self):
return self.article
OR
def __unicode__(self):
return self.article.question

Django tutorial choice_set

From the Django tutorial:
I've defined my models as follows:
from django.db import models
import datetime
from django.utils import timezone
# Create your models here.
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __unicode__(self): # Python 3: def __str__(self):
return self.question
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __unicode__(self): # Python 3: def __str__(self):
return self.choice_text
Where is choice_set defined and how does this work?
>>> p = Poll.objects.get(pk=1)
# Display any choices from the related object set -- none so far.
>>> p.choice_set.all()
I don't know how deep an explanation you want, but Django defines it for you when you do poll = models.ForeignKey(Poll).
You can read here about it.
choice_set wasn't defined anywhere.
Django creates API accessors for the “other” side of the relationship – the link from the related model to the model that defines the relationship. For example, a Poll object p has access to a list of all related Choice objects via the choice_set attribute: p.choice_set.all().
So choice_set. Where choice is your Choice model in lowercase and _set is kind of Django Manager Tool.
In details, you can read right here .

Django how the urls are resolved?

Im reviewing a sample DJango code and trying to understand how the urls are resolved?
list.html
Categories
{% for c in active_categories %}
{{c.name}}<br />
{% endfor %}
urls.py
from django.conf.urls import *
urlpatterns = patterns('ecomstore.catalog.views',
(r'^$','index',{'template_name':'catalog/index.html'},'catalog_home'),
(r'^category/(?P<category_slug>[-\w]+)/$','show_category',{'template_name':'catalog/category.html'},'catalog_category'),
(r'^product/(?P<product_slug>[-\w]+)/$','show_product',{'template_name':'catalog/product.html'},'catalog_product'),
)
The above html list all the categories without any problem and its called when I enter the following in the browser..[http:127.0.0.1:8000]
When I hover over - a href="{{p.get_absolute_url}} - I get the url resolved to--[http://127.0.0.1:8000/category/electronics/]
The p.get_absolute_url is resolved only to electronics but Im wondering how "category" is resolved in the url..
models.py
class Category(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(max_length=50,unique=True,help_text='Unique value for product page URL created from name')
description = models.TextField()
is_active = models.BooleanField(default=True)
meta_keywords = models.CharField("Meta Keywords",max_length=255,help_text="comma-delimited set of SEO Keywords for meta tag")
meta_description = models.CharField("Meta description",max_length=255,help_text="Content for description meta tag")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'categories'
ordering = ['-created_at']
verbose_name_plural = 'Categories'
def __unicode__(self):
return self.name
#models.permalink
def get_absolute_url(self):
return ('catalog_category',(),{'category_slug':self.slug})
Hope my question is clear...
get_absolute_url is a function defined inside the model (for example, Category) model like this:
class Category(models.Model):
name = models.CharField(max_length=200)
...
def get_absolute_url(self):
return "/category/%s/" % self.slug
It is also possible to use reverse function to resolve the url using a pattern defined in urls.py:
def get_absolute_url(self):
return reverse('catalog_category', args=[str(self.slug)])
which is almost equal to an old-fashioned form:
#models.permalink
def get_absolute_url(self):
return ('catalog_category', (), {'category_slug': str(self.slug)})
In both ways, calling the get_absolute_url method on a Category object, for example Category(name="electronics"), will result in the string: /category/electronics/.
As you can see in your urls.py, the second url pattern is named catalog_category, which appeard in the reverse function argument. When you call the reverse function, Django will look into urls.py files, looking for a pattern named catalog_category, and the final url will be generated by replacing the url parameter (category_slug) with self.slug.