Meanwhile using "view count" in my ecommerce project showing this error ('QuerySet' object has no attribute 'view_count')
views.py
class ProductDetailView(TemplateView):
template_name = 'product-detail-view.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
slug_url = self.kwargs['slug']
product = Product.objects.filter(slug=slug_url)
product.view_count += 1
product.save()
context["products"] = product
return context
models.py
class Product(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
image = models.ImageField(upload_to='products_img')
wholesale_rate = models.PositiveIntegerField()
amazon_rate = models.PositiveIntegerField()
description = models.TextField()
warranty = models.CharField(max_length=200, null=True, blank=True)
return_policy = models.CharField(max_length=200, null=True, blank=True)
view_count = models.PositiveIntegerField(default=0)
product = Product.objects.filter(slug=slug_url)
This return a queryset, not an object so you cannot access object field like this. Either use .first() to get an object or if you want to update all objects in queryset, then use
product.update(view_count = F('view_count') + 1)
Related
I have a listview where I'm trying to filter out products by category. Some products have a subcategory. When a product has a subcategory I want the listview to display them by subcategory.
Problem is: The listview works perfect for items with a subcategory, but does not work for items who do not have a subcategory. Where am I taking a wrong turn here?
Models:
class Category(models.Model):
category_name = models.CharField(max_length=200)
sub_category = models.CharField(max_length=200,blank=True,null=True)
category_picture = ResizedImageField(upload_to='category/', null=True, blank=True)
category_info = models.TextField(blank=True, null=True)
category_video = models.CharField(max_length=250,blank=True, null=True)
def __str__(self):
if self.sub_category is None:
return self.category_name
else:
return f" {self.sub_category}"
class Meta:
ordering = ['category_name']
class Bottle(models.Model):
category_name = models.ForeignKey('Category', on_delete=models.SET_NULL,null=True,blank=True)
brand = models.ForeignKey('Brand', on_delete=models.CASCADE)
bottle_name = models.CharField(max_length=255)
bottle_info = models.TextField()
bottle_tasting_notes = models.TextField()
bottle_barcode = models.IntegerField()
bottle_image = ResizedImageField(upload_to='bottles/',null=True, blank=True)
bottle_shop_link = models.CharField(max_length=250, null=True, blank=True)
def __str__(self):
return f"{self.brand}, {self.bottle_name}"
class Meta:
ordering = ['bottle_name']
View:
class BottlesByCategoryView(ListView):
model = Bottle
context_object_name = 'bottles'
#Filter bij subcategory in the category model. If no subcategory exists, load by category_name
def get_queryset(self):
if Bottle.objects.filter(category_name__sub_category=self.kwargs['category']) is None:
return Bottle.objects.filter(category_name__category_name=self.kwargs['category'])
else:
return Bottle.objects.filter(category_name__sub_category=self.kwargs['category'])
def get_context_data(self, **kwargs):
context = super(BottlesByCategoryView, self).get_context_data(**kwargs)
if Bottle.objects.filter(category_name__sub_category=self.kwargs['category']) is None:
context['category_info'] = Category.objects.filter(category_name=self.kwargs['category'])
else:
context['category_info'] = Category.objects.filter(sub_category=self.kwargs['category'])
return context
URLS:
path('BottlesByCategory/<str:category>/',BottlesByCategoryView.as_view(template_name='academy/bottlesByCat_list.html'),name='bottlesByCat_list'),
Can i not use if statements in the get_context_data and get_query_set?
i want to fetch the item of related subcategories but i am unable to fetch the items from that subcategories it is showing me the error
AttributeError: 'Subcategories' object has no attribute 'item'
so here is my code
my models
class Subcategories(models.Model):
categories = models.ForeignKey(Categories, on_delete=models.CASCADE, related_name='our_categories')
name = models.CharField(max_length=200, blank=False)
joined_date = models.DateTimeField(default=timezone.now,editable=False)
update_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
class Item(models.Model):
categories = models.ForeignKey(Categories, on_delete=models.CASCADE,)
subcategories = models.ForeignKey(Subcategories, on_delete=models.CASCADE, related_name='products')
can_buy = models.ForeignKey(For, on_delete=models.CASCADE,)
name = models.CharField(max_length=200, blank=False)
contain_size = models.CharField(max_length=10, blank=True)
first = models.ImageField(upload_to='items', blank=False)
second = models.ImageField(upload_to='items', blank=True)
third = models.ImageField(upload_to='items', blank=True)
fourth = models.ImageField(upload_to='items', blank=True)
fifth = models.ImageField(upload_to='items', blank=True)
item_vedio = models.FileField(upload_to='item_vedio', blank=True)
offered_price = models.FloatField(blank=False,)
actual_price = models.FloatField(blank=False)
about = models.TextField(blank=False, default="about" )
offer = models.CharField(max_length=4, blank=True)
def __str__(self):
return self.name
my urls.py
urlpatterns = [
path('<int:subcategory_id>/products/',Product.as_view(),name='product' ),
]
my views.py
class Product(View):
def get(self, request,):
category_list = Categories.objects.all()
return render (request, 'products.html', {'category_list': category_list })
def get(self, request, subcategory_id):
subcategory = get_object_or_404(Subcategories, pk=subcategory_id)
products = subcategory.item.all()
return render (request, 'products.html',{"subcategory_list" : products })
any idea what causing the issue and thank you for your time
The related name is products for subcategories Foreign key in Item model.
subcategory.products.all()
I have a model for musics and a model for comment of musics:
class music(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
STATUS_CHOICES = (('draft', 'Draft'), ('published', 'Published'),)
music = models.FileField()
music_image = models.ImageField(upload_to="images/")
singer_name = models.CharField(max_length=100)
music_name = models.CharField(max_length=100)
text_of_music = models.TextField()
create = models.DateField(auto_now_add=True, blank=True, null=True)
update = models.DateField(auto_now=True, blank=True, null=True)
publish = models.DateField(default=timezone.now, blank=True, null=True)
slug = models.CharField(max_length=250, unique_for_date='publish')
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
objects = models.Manager()
published = PublishedManager()
class Meta:
ordering = ('-publish',)
def get_absolute_url(self):
return reverse('music:music_detail',
kwargs={"id":self.id})
class comment(models.Model):
# Foreignkey for each music
For = models.ForeignKey(music, on_delete=models.CASCADE, related_name='post')
body = models.CharField(max_length=500)
created_on = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)
commented_by = models.ForeignKey(User, on_delete=models.CASCADE)
and this is my view:
def music_Detail(request, id=None):
user = request.user
template_name = 'music/music_detail.html'
Music = music.objects.all().filter(id=id)
new_comment = None
Comment = comment.objects.all().filter(active=True)
form = comment_form(data=request.POST)
if request.method == 'POST':
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.For = Music
new_comment.save()
form = comment_form()
return render(request, template_name, {'Music': Music, 'Comment': Comment, 'form': form})
Well, I get this error when I comment:
Cannot assign "<QuerySet [<music: m, majid kharatha>]>": "comment.For" must be a "music" instance.
How can I solve this problem and how can I display the information of the user who left this comment?
As the error says, you'll have to assign a single Music, not a queryset.
Instead of filter()ing to get a new queryset containing a single music,
Music = music.objects.all().filter(id=id)
you want to get() a single one:
Music = music.objects.get(id=id)
models .py
class ShopProfile(models.Model):
restaurant_name = models.CharField(max_length=100, blank=True)
slug = models.SlugField(max_length=140, unique=True)
related_user = models.ForeignKey(User, on_delete=models.CASCADE)
class Item(models.Model):
title = models.CharField(max_length=100)
price = models.FloatField()
created_by = models.ForeignKey(ShopProfile, on_delete=models.CASCADE)
class OrderItem(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE)
ordered = models.BooleanField(default=False)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
class Order(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE)
items = models.ManyToManyField(OrderItem)
total = models.FloatField(blank=True, null=True)
views.py
class InComingOders(TemplateView):
template_name = 'shop/incoming.html'
model = Order
def get_context_data(self, **kwargs):
context = super(InComingOders, self).get_context_data(**kwargs)
context['list_orders'] = Order.objects.filter(
items=(OrderItem.objects.filter(
item=(Item.objects.filter(
created_by =created_by=ShopProfile.objects.get(related_user=self.request.user))))))
return context
I need to get all the orders corresponded to each shop by relating the field created_by in the shop profile.
if a customer places an order, that item created by shop profile it must display in the shop
Simply, something like this,
list_orders = Order.objects.filter(items__item__created_by=self.request.user)
#views.py
class InComingOders(TemplateView):
...
def get_context_data(self, **kwargs):
context = super(InComingOders, self).get_context_data(**kwargs)
context['list_orders'] = Order.objects.filter(items__item__created_by=self.request.user)
return context
For more and detailed info, refer Lookups that span relationships--(Django-Doc)
I have a Property Model as follows =
class Property(models.Model):
property_type = models.CharField(max_length=255, default='Apartment')
specifications = models.CharField(max_length=255, default='Basic')
built_up_area = models.FloatField(max_length=6, null=False, default=0)
total_area = models.FloatField(null=False, default=0)
number_of_bedrooms = models.CharField(max_length=3, default=1)
number_of_bathrooms = models.CharField(max_length=3, default=1)
number_of_parking_spaces = models.CharField(max_length=2, default=0)
address_line_one = models.CharField(max_length=255, null=False)
address_line_two = models.CharField(max_length=255, null=True, default=None)
connectivity = models.CharField(max_length=255, default=None, null=True)
neighborhood_quality = models.CharField(max_length=255, default=None,
null=True)
comments = models.CharField(max_length=255, default=None, null=True)
city = models.ForeignKey('City')
state = models.ForeignKey('State')
pin_code = models.ForeignKey('PinCode')
developer = models.ForeignKey('Developer', null=True, default=None)
owner = models.ForeignKey('Owner', null=True, default=None)
created_by = models.ForeignKey('custom_user.User')
project = models.ForeignKey('Project')
def __unicode__(self):
return self.property_type
class Meta:
verbose_name_plural = 'Properties'
And a City model as follows -
class City(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(unique=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(City, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
Now I want to make a single form where I can enter the Property details and while entering the city, I can enter the name of the city instead of selecting from the dropdown list.
So how do I create the inline formset using the inlineformset_factory to create the form?
==EDIT==
I've tried to use the following code to create the formset
CityFormset = inlineformset_factory(City, Property,
fields=('city',),
extra=0,
min_num=1,
can_delete=False)
You've misunderstood what an inline formset is. It's for editing the "many" side of a one-to-many relationship: that is, given a parent model of City, you could edit inline the various Properties that belong to that city.
You don't want a formset at all to simply edit the single City that a property can belong to. Instead, override the city field within your Property form to be a TextField, and either create a new City or find an existing one in the clean_city method.
class PropertyForm(forms.ModelForm):
city = forms.TextField(required=True)
class Meta:
model = Property
exclude = ('city',)
def __init__(self, *args, **kwargs):
super(PropertyForm, self).__init__(*args, **kwargs)
if self.instance and not self.data:
self.initial['city'] = self.instance.city.name
def save(self, commit=True):
city_name = self.cleaned_data['city']
city, _ = City.objects.get_or_create(name=city_name)
instance = self.save(commit=False)
instance.city = city
if commit = True:
instance.save()
return instance