I'm about to make a simple webshop, and are currently working on my add to cart button.
When I click the add to cart button right now, it returns an error as follows:
FieldError at /add-to-cart/box-1/
Exception Value:
Cannot resolve keyword 'ordered' into field. Choices are: box, box_id, id, order, quantity, title
Related Code
views.py:
def add_to_cart(request, slug):
# Get the item from the slug via get_object_or_404 method
box = get_object_or_404(Box, slug=slug)
# Check if the user have an order
order_box = OrderBox.objects.create(box=box)
order_qs = OrderBox.objects.filter(user=request.user, ordered=False)
if order_qs.exists():
order = order_qs[0]
# Check if order item is in the order
if order.box.filter(box__slug=box.slug).exists():
order_box.quantity += 1
order_box.save()
else:
ordered_date = timezone.now()
order = Order.objects.create(user=request.user, ordered_date=ordered_date)
order.items.add(order_box)
return redirect('webshop:shop-box', slug=slug)
models.py
class Order(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
items = models.ManyToManyField(OrderBox)
start_date = models.DateTimeField(auto_now_add=True)
ordered_date = models.DateTimeField()
ordered = models.BooleanField(default=False)
def __str__(self):
return self.user.username
I've been searching around, and can find different questions on this topic, however I can't understand what the issue is.
I'd much appreciate some help to figure out where I've mistaken, thank you!
It looks like OrderBox does not have a field called ordered (or user for that matter), your Order model does. So without knowing too much about your project, you either need to create a queryset for your Order model instead of OrderBox or filter your OrderBox queryset by their related Order models (if they are related, it appears so from the available fields listed in the error message). If this is the case, you could
try OrderBox.objects.filter(order__user=request.user, order__ordered=False)
Related
I'm trying to create a 'saved post' feature on a website. I'm struggling with how to create a query that I can use to populate my HTML template with posts.
Here are my models:
class User(AbstractUser):
pass
class Post(models.Model):
title = models.CharField(max_length=200)
description = models.CharField(max_length=500)
class SavedPost(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
user = models.ForeignKey (User, on_delete=models.CASCADE, null=True)
My .views looks like this
def savedpostsview(request):
posts = Post.objects.all
savedposts = posts.savedpost_set(user = request.user)
return render(request, "posts/savedposts.html",{
'savedposts': savedposts
})
Right now I'm getting the error "'function' object has no attribute 'savedpost_set'".
I know I'm getting something wrong syntactically, but I've been reading documentation forever and can't figure out what it is for the life of me. Does anybody have any insight into what I'm doing wrong?
first of all here Post.objects.all all() is a function and thats why error is "'function' object has no attribute 'savedpost_set'"
You should call Post.objects.all() this will return queryset.
Then You are trying to reverse query on queryset which not possible and will throw error.
All you want is this Post.objects.filter(savedpost__user=request.user)
I am building a BlogApp and I was working on a feature and I am stuck on a error.
operator does not exist: character varying = integer
LINE 1: ...d" = "taggit_tag"."id") WHERE "taggit_tag"."name" IN (SELECT...
I am trying to retrieve all the comments commented by user from Tags which were used in comment's post.
When I access the comments then it is keep showing that error when i access the variable in template.
models.py
class Post(models.Model):
post_user = models.ForeignKey(User, on_delete=models.CASCADE)
post_title = models.CharField(max_length=30)
tags = models.TaggableManager()
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post_of = models.ForeignKey(Post, on_delete=models.CASCADE)
views.py
class page(request):
tagQuery = Tag.objects.filter(post__comment__user=request.user)
#this is showing error
subquery = Comment.objects.filter(post_of__tags__name__in=tagQuery)
context = {'subquery':subquery}
return render(request, 'page.html', context)
It was showing
The QuerySet value for an exact lookup must be limited to one result using slicing.
So i used __in but then it keep showing that error.
Any help would be much Appreciated. Thank You
Rather than filtering according to queryset itself, you need to filter according to values of certain field:
class page(request):
tagQuery = Tag.objects.filter(post__comment__user=request.user)
subquery = Comment.objects.filter(post_of__tags__name__in=tagQuery.values_list('name'))
context = {'subquery':subquery}
return render(request, 'page.html', context)
I am having two models, a User model and a Payment model and there is on to many relationship between them. User has multiple Payments. What I am trying to achieve is sorting the User model as per the Payment's created_at field.
I am trying to modify the Queryset and then I'll be using the annotated field latest_tran for sorting.
def get_queryset(self, request):
qs = super(ClubbedPaymentAdmin, self).get_queryset(request)
qs = qs.annotate(
latest_tran=Greatest(Payment.objects.filter(user=F('id')).values_list('created_at', flat=True)))
return qs
But I am having below error.
Greatest must take at least two expressions
So it seems like I am making a mistake when evaluating the list of Payments. Or may be like I am taking a wrong approach.
Any help would be much appreciated.
Thank you.
Edit
I am using the default User model for users which are there in django
My Payment model looks like this -
class Payment(models.Model):
amount = models.FloatField('Points', max_length=10)
purchase_token = models.TextField(max_length=250)
user = models.ForeignKey(User, on_delete=models.CASCADE)
note = models.TextField(max_length=1000, default=None, blank=True)
created_at = models.DateTimeField('Transaction Date')
updated_at = models.DateTimeField('Updated at', auto_now=True)
Greatest does not take the maximum, it takes the largest of the different parameters, so Greatest('foo', 'bar') will take the largest of the foo and bar column.
What you need is Max [Django-doc]. You can make use of the name separated by an underscore, so:
from django.db.models import Max
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).annotate(
latest_tran=Max('payment__created_at')
)
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
Something like this, using the Max(...) ?
from django.db.models import Max
def get_queryset(self, request):
qs = super(ClubbedPaymentAdmin, self).get_queryset(request)
qs = qs.annotate(latest_tran=Max('payment__created_at'))
return qs
I am very much new in django restframework,I tried to create a search api.
I have 2 models designed
class Category(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Product(models.Model):
product_name = models.CharField(max_length=255)
product_Comments = models.CharField(max_length=255)
size = models.CharField(max_length=10, null=True)
product_Status = models.BooleanField(default=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.product_Description
I want to create a rest API, in which I can search the category and based on the search i want to list the product which related to that category. How can I do it.
My Views.py
class productList(generics.ListAPIView):
serializer_class = productSerializer
def get_queryset(self):
queryset = Product.objects.all()
search = self.request.query_params.get('search', None)
if search is not None:
queryset = queryset.filter(product_name__icontains=search)
my urls
path('product_search/',views.productList.as_view()),
You're almost there, you just need to add filtering.
Also, you almost never need to override the get() method of a generic view. Look for the method that let's you do the least amount of work. For any view, you will do most work in get_queryset and a view specific method:
List: view.list()
Create: view.create()
Retrieve: view.retrieve()
Update: view.perform_update()
Destroy: view.perform_destroy()
The rest can be customized by setting the correct class attributes. There are very few cases where it is necessary to override a view's "get" or "post" methods.
So, get_queryset is the place to modify the collection of objects that you are going to work on. This is perfect for filtering and thus search. A lot of work is already available in DRF and you can use it:
class productList(generics.ListAPIView):
serializer_class = productSerializer
def get_queryset(self):
queryset = Product.objects.all()
search = self.request.query_params.get('search', None)
if search is not None:
queryset = queryset.filter(category__name__icontains=search)
# don't forget to return the queryset
return queryset
For filtering the Products based on category name is,
Product.object.filter( category__name = 'category_name')
So I've been stuck with a design problem for the last couple of days and have sunk countless hours into it, to no avail.
My problem is that I wish return all the active Articles. I have made a method within the model, however am unable to use .filter(is_active=True)which would be the worlds best solution.
So now I have made the method into one long filter in the ArticleManager, the problem being that I cannot seem to figure out a way to count the current clicks in a way that can be useful to me. (The current_clicks method in the Article model is what I am aiming for).
Models.py
class ArticleManager(models.Manager):
def get_queryset(self):
return super(ArticleManager, self).get_queryset().filter(article_finish_date=None).filter(article_publish_date__lte=timezone.now())
#this is where i need something to the effect of .filter(article_max_clicks__gt=click_set.count())
class Article(models.Model):
article_name_text = models.CharField(max_length=200)
article_max_clicks = models.IntegerField(default=0)
article_creation_date = models.DateTimeField('date created')
article_publish_date = models.DateTimeField('date published', null=True, blank=True)
article_finish_date = models.DateTimeField('date finished', null=True, blank=True)
def __str__(self):
return self.article_name_text
def is_active(self):
if self.article_finish_date==None:
if self.article_publish_date <= timezone.now():
return self.current_clicks() < self.article_max_clicks
else:
return False
else:
return False
def current_clicks(self):
return self.click_set.count()
is_active.boolean = True
actives = ArticleManager()
class Click(models.Model):
click_article = models.ForeignKey(Article, on_delete=models.CASCADE)
click_user = models.ForeignKey(User, on_delete=models.CASCADE)
click_date = models.DateTimeField('date clicked')
def __str__(self):
return str(self.id) + " " + str(self.click_date)
This is how the clicks are created in views.py if this helps
article.click_set.create(click_article=article, click_user=user, click_date=timezone.now())
If anyone has any sort of idea of how abouts I should do this it would be greatly appreciated!
Many thanks in advance, just let me know if you need anymore information!
Django's annotate functionality is great for adding properties at the time of querying. From the docs -
Per-object summaries can be generated using the annotate() clause. When an annotate() clause is specified, each object in the QuerySet will be annotated with the specified values.
In order to keep your querying performance-minded, you can use this in your manager and not make the (possibly very slow) call of related objects for each of your Articles. Once you have an annotated property, you can use it in your query. Since Django only executes your query when objects are called, you can use this annotation instead of counting the click_set, which would call a separate query per related item. The current_clicks method may still be useful to you, but if calling it for multiple articles your queries will add up quickly and cause a big performance hit.
Please note - I added a related_name of clicks keyword arg to your click_article field in order to use it in place of 'click_set'.
In addition, you'll see the use of Q objects in the query below. What this allows us to do is chain together multiple filters together. These can be nested while using AND (,) / OR(|) operands. So, a reading of the Q objects below would be:
Find all articles where article publish date is before now AND (article has no finish date OR article finish date is after now)
from django.db.models.query import Q,Count
class ArticleManager(models.Manager):
def get_queryset(self):
return super(ArticleManager, self).get_queryset().filter(
Q(article_publish_date__lte=timezone.now()),
( Q(article_finish_date__isnull=True)|
Q(article_finish_date__gte=timezone.now())
).annotate(
click_count=Count('clicks')
).filter(
article_max_clicks__gt=click_count
)
class Article(models.Model):
actives = ArticleManager()
def current_clicks(self):
return self.clicks.count()
# Now you can call Article.actives.all() to get all active articles
class Click(models.Model):
click_article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='clicks') # added a related_name for more explicit calling of prefetch_related