I have a category Model and a Product Model in my django application... the product model has a many2many field pointing to the category model... and the product model has a added field to denote when it was created.
how do i filter the categories model based on the added field value of the product?
class Category(models.Model):
#this model SHOULD BE managed by the platform admin
title = models.CharField(max_length=100)
slug = models.SlugField(blank=True)
description = models.CharField(max_length=255, blank=True, null=True)
items_count = models.PositiveIntegerField(null=True, blank=True)
updated = models.DateTimeField(auto_now=True)
image = models.ImageField(upload_to='categories_images',help_text='Generic Image describing the category very very well', null=True, blank=True)
def __str__(self):
return str(self.slug)
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super().save(*args, **kwargs)
class Product(models.Model):
title = models.CharField(max_length=50)
image = models.ImageField(upload_to='uploaded_products/', default="products/default_product.png")
description = models.TextField(max_length=255, null=True, blank=True)
categories = models.ManyToManyField(Category,related_name='products', blank=True)
tags = models.ManyToManyField(Tag, blank=True)
stock = models.PositiveIntegerField(default=1, blank=True)
added = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
uploader = models.ForeignKey(Account, on_delete=models.CASCADE, blank=True, null=True)
def __str__(self):
return self.title
i want to be able to do a query for the current trending categories based on the added field of the product.
We can first look for each Category when was the most recent Product that was added with .alias(…) [Django-doc], or with .annotate(…) [Django-doc] prior to django-3.2. We annotate this with:
from django.db.models import Max
Category.objects.alias(
most_recent_change=Max('products__added')
)
Then we can retrieve the objects through filtering. For example if we only want to retrieve Categorys updated in the last 24 hours, we can filter with:
from datetime import timedelta
from django.db.models import Max
from django.db.models.functions import Now
Category.objects.alias(
most_recent_change=Max('products__added')
).filter(
most_recent__gte=Now()-timedelta(days=1)
)
or we can make use of the timestamp provided by Django itself:
from datetime import timedelta
from django.utils.timezone import now
from django.db.models import Max
Category.objects.alias(
most_recent_change=Max('products__added')
).filter(
most_recent__gte=now()-timedelta(days=1)
)
Related
models.py
from django.db import models
class Images(models.Model):
def upload_path(instance, filename):
return '/images/'.join([filename])
image = models.ImageField(upload_to=upload_path, blank=True, null=True)
logits = models.BinaryField()
#customer = models.ForeignKey(Customer ,on_delete=models.DO_NOTHING, default=None)
class Customer(models.Model):
customer_id = models.BigIntegerField(unique=True)
first_name = models.CharField(max_length=300)
last_name = models.CharField(max_length=300)
images = models.ForeignKey(Images ,on_delete=models.DO_NOTHING, default=None)
def __str__(self):
return str(self.customer_id)
My problem is i want to be able to assign multiple images to single user which should be possible because of ForeignKey but i don't seem to get it to work like that.
I want multiselect field just like in manytomanyfield but in foreignkey field.
My problem is [I] want to be able to assign multiple images to [a] single user which should be possible because of ForeignKey but [I] don't seem to get it to work like that.
No: A ForeignKey is a many-to-one relation: it means that many Customers can refer to a, possibly the same, single Images. If you want to use multiple Images then you need to write the ForeignKey in the opposite direction, so:
from django.db import models
class Image(models.Model):
def upload_path(instance, filename):
return f'/images/{filename}'
image = models.ImageField(upload_to=upload_path, blank=True, null=True)
logits = models.BinaryField()
customer = models.ForeignKey(
'Customer',
on_delete=models.SET_NULL,
null=True,
related_name='images'
)
class Customer(models.Model):
customer_id = models.BigIntegerField(unique=True)
first_name = models.CharField(max_length=300)
last_name = models.CharField(max_length=300)
def __str__(self):
return f'{self.customer_id}'
I'm making a searchbar for a site I'm working on and I'm having trouble when I want to filter different fields from different models (related between them) Here are my models:
class Project(models.Model):
name = models.CharField(max_length=250)
objective = models.CharField(max_length=250)
description = models.TextField()
launching = models.CharField(max_length=100, null=True, blank=True)
image = models.ImageField(
upload_to='imgs/', null=True, blank=True)
image_thumbnail = models.ImageField(
upload_to='thumbnails/', null=True, blank=True)
slug = models.CharField(max_length=250)
class Meta:
db_table = 'project'
def __str__(self):
return self.name
class Institution(models.Model):
name = models.CharField(max_length=250)
project = models.ManyToManyField(Proyecto)
class Meta:
db_table = 'institution'
def __str__(self):
return self.name
And I want to be able to search by the name of the project or the institution, but my code only takes the institution's name.
def searchbar(request):
if request.method == 'GET':
search = request.GET.get('search')
post = Project.objects.all().filter(name__icontains=search, institution__name__icontains=search)
return render(request, 'searchbar.html', {'post': post, 'search': search})
How can I search for all the projects that match by its name OR the institution's name?
BTW, I'm using SQL, not sure if it's relevant, but I thought I should add that info.
You can .filter(…) [Django-doc] with Q objects [Django-doc]:
from django.db.models import Q
Project.objects.filter(Q(name__icontains=search) | Q(institution__name__icontains=search))
or you can work with the _connector parameter:
from django.db.models import Q
Project.objects.filter(
name__icontains=search,
institution__name__icontains=search,
_connector=Q.OR
)
I am trying to get all products related to an orderitem but am having a problem doing the query.
I want to list all products in an orderitem. Hope i have provided everything needed.
from django.core.validators import RegexValidator
from django.db import models
from django.urls import reverse
from django.utils.text import slugify
from django.contrib.auth import get_user_model
class Order(models.Model):
ref_code = models.CharField(max_length=20, blank=True, null=True)
first_name = models.CharField(('first name'), max_length=30, blank=True)
last_name = models.CharField(('last name'), max_length=30, blank=True)
class Product(models.Model):
category = models.ForeignKey(Category,related_name='products',on_delete=models.CASCADE)
name = models.CharField(max_length=200, db_index=True, unique=True)
class OrderItem(models.Model):
order = models.ForeignKey(Order,related_name='items',on_delete=models.CASCADE)
product = models.ForeignKey(Product,related_name='order_items',on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField(default=1)
slug = models.SlugField(max_length=200, db_index=True)
Try this:
# Get list of product ids of a particular order
product_ids = OrderItem.objects.filter(order=order).values_list('product', flat=True)
# Get products from list of product ids
products = Product.objects.filter(id__in=product_ids)
Let me know if it helps :)
an idea to do thas
# For all_entries
all_entries = OrderItem.objects.all() #or all_entries = OrderItem.filter(order = order)
# one orderItem
for oi in orderItem:
products_of_one_oi = oi.product
for product in products_of_one_oi:
print(product)
my apologies as I am new to Django and this seems like a "Django 101" type problem, but I just can't seem to get it to work. I have a Django model for "Services" which has a related model for "Keywords" via a one-to-many relationship. I'm simply trying to return the related keywords when I query the services, but when I run the view, I keep getting the error:
Invalid field name(s) given in select_related: 'keyword'. Choices are: (none)
My models are as follows:
from uuid import uuid4
from django.db import models
from django.utils.text import slugify
from blog.models import Tag, Category
class Service(models.Model):
id_service = models.UUIDField(primary_key=True, default=uuid4, editable=False)
created_ts = models.DateTimeField(auto_now_add=True)
updated_ts = models.DateTimeField(auto_now=True)
service_name = models.CharField(
db_index=True, max_length=50, blank=False, null=False
)
slug = models.CharField(max_length=50, unique=True)
font_awesome_icon = models.CharField(blank=True, null=True, max_length=30)
service_image = models.ImageField(
blank=True, null=True, upload_to="images/services", max_length=None
)
service_page_image = models.ImageField(
blank=True, null=True, upload_to="images/services", max_length=None
)
service_description = models.TextField(blank=False, null=False)
service_description_brief = models.CharField(
max_length=200, blank=False, null=False
)
rank = models.IntegerField()
def save(self, *args, **kwargs):
self.slug = slugify(self.service_name)
super(Service, self).save(*args, **kwargs)
def __str__(self):
return self.service_name
class ServiceKeyword(models.Model):
id_servicekeywords = models.UUIDField(
primary_key=True, default=uuid4, editable=False
)
created_ts = models.DateTimeField(auto_now_add=True)
updated_ts = models.DateTimeField(auto_now=True)
keyword = models.CharField(max_length=60, blank=False, null=False)
service = models.ForeignKey(Service, on_delete=models.CASCADE)
def __str__(self):
return self.keyword
And the view that is throwing the error is:
import random
import markdown2
import geoip2.database
import datetime
from django.views.generic.base import TemplateView
from django.views.generic.list import ListView
from django.core.paginator import Paginator
from django.http import Http404
from django.shortcuts import render
from django.urls import reverse
from services.models import Service, ServiceKeyword
class ServiceView(TemplateView):
template_name = "services/service.jinja"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
servicename = self.kwargs["servicename"]
service_list = Service.objects.select_related("keyword").order_by("rank")
context["service_list"] = service_list
context["faq_list"] = Post.objects.filter(categories__slug=servicename)
for faq in context["faq_list"]:
faq.content = markdown2.markdown(faq.content)
# Get service with that slug and take from list
service = service_list.filter(slug=servicename)[0]
context["keyword_list"] = service.keyword.all().order_by("?")[7]
context["service"] = service
)
return context
Any help from the pros would be greatly appreciated, as I've looked at the docs and spend an inordinate amount of time trying to fix. Thank you!
Defining a related_name on your field definition should solve your problem :
class ServiceKeyword(models.Model):
...
service = models.ForeignKey(Service, related_name='keyword', on_delete=models.CASCADE)
...
You can find the documentation for the related_name HERE
Recently I'm working on a blog. where a post has category and subcategory.
This is my models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from ckeditor_uploader.fields import RichTextUploadingField
class Category(models.Model):
title = models.CharField(max_length=50, unique=True)
def __str__(self):
return f"{self.title}"
class SubCategory(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
title = models.CharField(max_length=50, unique=True)
def __str__(self):
return f"{self.title}"
class Author(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(max_length=100)
phone_no = models.CharField(max_length=14)
details = models.TextField(null=True,blank=True)
def __str__(self):
return f"{self.name}"
class Post(models.Model):
author = models.ForeignKey(Author, default=1,blank=True,
null=True, on_delete=models.SET_DEFAULT)
category = models.ForeignKey(Category,on_delete=models.CASCADE,
null=True)
sub_category = models.ForeignKey(SubCategory,
on_delete=models.CASCADE, null=True, blank=True)
title = models.CharField(max_length=250)
featured_image = models.ImageField(
upload_to="post_featured_image",null=False )
content = RichTextUploadingField()
podcast = models.FileField(upload_to="post_podcast",
blank=True,null=True)
uploaded_on = models.DateTimeField(default=timezone.now)
viewed = models.IntegerField(default=0,editable=False)
def __str__(self):
return f"{self.title}"
Now I can choose category and subcategory for a post from Django admin panel. But the problem is I can choose one category and any subcategory even the subcategory is not the child of the selected category. So a post has a category and a subcategory. But the subcategory's parent category is not same as post's category. So I want that I can only choose those subcategories which is the child of selected categories that I choose for the post. Like next field has to be dependent on the previous field. How to do that?
sorry for my bad English. Thank you.