3

I have 3 Models Product,Company Categories.

class Product(Meta):
    categories = models.ManyToManyField(Category)
    company = models.ForeignKey(Company, related_name='products', on_delete=models.CASCADE)
updated_at = models.DateTimeField(auto_now_add=False, auto_now=True)

I need:

  • to get all the products of a company
  • show the product first category
  • count the number products per company and show
  • order products by reverse updated_at

I start from:

1. Company.objects.get(pk=company_pk).prefetch_related('products')

will give me an error, because get returns an object:

class CompanyProductListView(ListView):
 model = Company
 template_name_suffix = '_company_list'

def get_queryset(self):
    company_pk = self.kwargs.get('pk')
    return Company.objects.get(pk=company_pk).prefetch_related('products')

get without prefetch works.

  1. return Company.objects.filter(pk=company_pk).prefetch_related('products')

there is no error, but in template:

 {% for company in company_list %}
        {{ company.name}}
    {% endfor %}

I loop even is one, but doesn't show me anything.

Besides that I need to attach first category to each product, and count the number of products

I'm thinking on access something like this:

{{company.name}}

{% for product in company.products %}
   {{ product.name }}
   {{ product.category }}
user3541631
  • 3,686
  • 8
  • 48
  • 115
  • Can you post your entire code for your 2nd solution. I don't see why the for loop won't work unless it found no objects with pk=company_pk. It probably seems like a typo/silly mistake. – oxalorg Dec 08 '17 at 19:23
  • @oxalorg I added the CBV code, in template is just what you see – user3541631 Dec 08 '17 at 19:27
  • Also, what do you mean by "I need to attach first category to each product"? On what basis do you define "first"? (date added?) – oxalorg Dec 08 '17 at 19:29
  • @oxalorg first, the creation date so the category id, I know that there is a first() method for Queryset; attach Whe I show in html, at the top I show some fields about company than product.name, product desc, product category – user3541631 Dec 08 '17 at 19:30

1 Answers1

2

This query will get a little complicated, but should help you solve your issue.

PS: I haven't tested this but should mostly work. Will take a deeper look once I get some more time.

First we get the company we want:

company = Company.objects.get(pk=company_pk)

Then we fetch all the first categories for all products, it can be done by using this question as a guide:

first_categories = Category.objects.order_by('product__id', '-id').distinct('product__id')

Now we use the first_categories to use to limit the amount of data we prefetch (giving this a different perspective, we will query the Product model instead of the Company model)

product_list = Products.objects.filter(company=company).prefetch_related(
    Prefetch('categories', queryset=first_categories)
)

def get_queryset():
    company_pk = ...
    company = ...
    first_categories = ...
    product_list = ...
    return product_list
oxalorg
  • 2,768
  • 1
  • 16
  • 27
  • thanks, but now being three will not work overwriting the get_queryset, so I need to keep one in queryset and add the others in context ? – user3541631 Dec 08 '17 at 20:08
  • @user3541631 You need the `company` and `first_categories` only to get the `product_list`. Since your CBV is `CompanyProductListView`, you need a list of products. So jsut return the product_list as the query set. I've updated the answer to reflect the changes. – oxalorg Dec 08 '17 at 20:12
  • thanks, but in this case how to I access in template also company info ? I update my question to see how I want to access the context in template – user3541631 Dec 09 '17 at 07:42