Django query categories, exclude those without posts - django

I have these two models, post and categories.
class Category(models.Model):
""" Categories """
name = models.CharField(max_length = 80, help_text="Enter a descriptive and unique category name.")
slug = models.SlugField(max_length = 250, help_text="The slug is used to link category pages.")
class Post(models.Model):
""" Blog posts """
author = models.ForeignKey(User, related_name='blog_posts', on_delete = models.CASCADE)
category = models.ForeignKey(Category, related_name = 'blog_posts', on_delete = models.CASCADE)
title = models.CharField(max_length=250)
body = models.TextField(help_text = "Type your blog post using plain text or mark-down format.")
I am trying to query all the categories that have posts, excluding categories which don't have yet posts. The SQL equivalent of:
SELECT * FROM category WHERE id IN (SELECT DISTINCT(category_id) FROM post)
Many thanks!

You can use annotation to count the posts and then filter based on the result:
from django.db.models import Count
Category.objects.annotate(posts_count=Count("blog_posts")).filter(post_count__gt=0)

Related

Need to Fetch specific foreign key object product from database in Django

Hi everyone I am new at Django and working on e-commerce site. I create a model name category and pass it to model shop by using foreign key. In Category model I have category Sale and i want to fetch all products that have category sale in my landing page and rest of us in shop page. Any one please help me how I do it?
My model.py code is:
class category(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class shop(models.Model):
s_id = models.AutoField(primary_key=True)
s_name = models.CharField(max_length=50)
s_category = models.ForeignKey(category, on_delete= models.CASCADE)
s_artical_no = models.IntegerField(default=0)
View.py:
def index(request):
prod = shop.objects.get(s_category = 4)
params = {'prod': prod}
return render(request, "main/index.html", params )
Use related_name to accomplish this
class shop(models.Model):
s_category = models.ForeignKey(category, on_delete= models.CASCADE, related_name='shop_list')
In views.py
def index(request):
specific_category = category.objects.get(id=4)
prod = category.shop_list.all() #use related_name here
params = {'prod': prod}
return render(request, "main/index.html", params )
Hint: your classes names should follow the UpperCaseCamelCase convention so it should be Shop, Category
s_category is a category instance, you can't pass a category id. First get the category object for "Sale" i.e.
sale_category = category.objects.get(pk=4)
then simply use
prod = sale_category.shop_set.all()
As a side note, try to use PEP-8 compliant class names. The way you name your classes is confusing

django queryset filter foreignkey

I'm having problems trying to use the queryset filter with my models.
It is a control for posts in groups.
This is my code:
class Post(models.Model):
title = models.CharField(max_length=120)
content = models.TextField()
class Group(models.Model):
title = models.CharField(max_length=200)
url = models.URLField(unique=True)
class Control(models.Model):
published = models.DateField(auto_now=False, auto_now_add=False)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
I'm trying to get all posts from a group with the title "title":
queryset_list = Control.objects.filter(group__control="title")
My models might nit be right, I'm new to this.
Any help?
Maybe it typo error?
queryset_list = Control.objects.filter(group__title="title")
# ^^^^^^
posts_title = queryset_list.values('post__title')
First, you should add a ManyToManyField on Group (docs):
class Group(models.Model):
title = models.CharField(max_length=200)
url = models.URLField(unique=True)
posts = models.ManyToManyField('Post', through='Control')
The other two models remain the same, but now you can easily grab posts for a Group:
posts = Group.objects.get(title='some title').posts.all()

How to write model for tags database

I want to create an object with tags and categories. I read on https://stackoverflow.com/a/20871 that the tags schema should be like this,
> Table: Item Columns: ItemID, Title, Content
>
> Table: Tag Columns: TagID, Title
>
> Table: ItemTag Columns: ItemID, TagID
However, I want to associate every tags with a category.
What I want is an item can have only one category and multiple tags. And the tags are also associated with/group in the category.
I am not very clear how to use the model relationship, this is what I come up with:
class Item(models.Model):
title = models.CharField(max_length=100)
content = models.TextField(blank=True)
class Tags(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
class ItemTag(models.Model):
itemid = models.ForeignKey(Item) #not sure if this is correct to use foreignkey
tagid = models.ForeignKey(Tags)
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
#not sure how to do this category grouping
class CategoryTags(models.Model):
catid = models.Foreignkey(Category)
tagid = models.Foreignkey(Tags)
There are plenty tags will be created, and it will be use in the search keyword for the Items. Not sure if this is the best idea to cope with.
Based on your task description (An item can have only one category and multiple tags. And the tags are also associated with/group in the category.) I'd suggest the following schema:
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
class Tag(models.Model):
name = models.CharField(max_length=100, db_index=True)
slug = models.SlugField(unique=True)
# the tag belongs to a category
category = models.ForeignKey(Category, blank=True)
class Item(models.Model):
title = models.CharField(max_length=100, db_index=True)
content = models.TextField(blank=True)
# the item belongs to one category
# if having a category is required please remove blank=True
category = models.ForeignKey(Category, blank=True)
tags = models.ManyToManyField('Tag')
ForeignKey is a many-to-one relationship. In your case many items belong to one category.
See also ManyToMany field.

search query result in django

Here is my model
class News(models.Model):
title = models.CharField(max_length=500)
published_date = models.CharField(max_length=100)
description = models.TextField()
details = models.TextField()
status = models.BooleanField(default=False)
crawler = models.ForeignKey('Crawler')
category = models.ForeignKey('Category')
And the view for the news is
class DisplayNewsView(TemplateView):
template_name = "news_listing.html"
#paginate_by = 10
def get_context_data(self, **kwargs):
context = super(DisplayNewsView, self).get_context_data(**kwargs)
categories_list = Category.objects.all().filter(created_by=self.request.user)
context['news_list'] = []
for categories in categories_list:
print(categories)
for crawler in categories.crawlers.get_queryset():
#print(categories)
print(crawler)
crawler_list = News.objects.filter(
Q(category=categories),
Q(crawler=crawler) | Q(crawler=crawler))
#print(crawler_list)
context['news_list'].append(crawler_list)
return context
I have displayed the news in template.
I want to search the news according to time. I mean the news from "date" to "date" as per the published date in news model.
My model for category is
class Category(models.Model):
category = models.CharField(max_length=50)
identifier = models.CharField(max_length=50, unique=True)
level_1_words = models.TextField()
level_2_words = models.TextField()
created_by = models.ForeignKey(User,null=True)
crawlers = models.ManyToManyField('Crawler',related_name='crawler_name')
class Meta:
verbose_name_plural = "Categories"
def __unicode__(self): # Python 3: def __str__(self):
return self.category
Can anyone plz help to to search the news according to publish date.
I want it to be done like from "date" to "date" submit.
When user click the submit button I want the news to be filtered..
It would be great help if someone tell me how to download the searched news in csv too. thanx in advance
You first need to make that field of the date a DateField instead of CharField
This is how to query date range in django
News.objects.filter(pub_date__lte=datetime(2014, 5, 30), pub_date__gte=datetime(2014, 1, 30))
Another example would be
News.objects.filter(pub_date__lte=datetime(2014, 5, 30), pub_date__gte=datetime(2014, 1, 30)).exclude(datetime.date.today())
for more information on django queries check out the docs # Making queries in Django

django queryset for many-to-many field

I have the following Django 1.2 models:
class Category(models.Model):
name = models.CharField(max_length=255)
class Article(models.Model):
title = models.CharField(max_length=10, unique=True)
categories = models.ManyToManyField(Category)
class Preference(models.Model):
title = models.CharField(max_length=10, unique=True)
categories = models.ManyToManyField(Category)
How can I perform a query that will give me all Article objects that are associated with any of the same categories that a given Preference object is related with?
e.g. If I have a Preference object that is related to categories "fish", "cats" and "dogs", I want a list of all Articles that are associated with any of "fish", "cats" or "dogs".
Try:
preference = Preference.objects.get(**conditions)
Article.objects.filter(categories__in = preference.categories.all())
Article.objects.filter(categories__in=myPreferenceObject.categories.all())