代码之家  ›  专栏  ›  技术社区  ›  Nikita Tonkoskur

“ReverseManyToOneDescriptor”对象没有“all”属性

  •  0
  • Nikita Tonkoskur  · 技术社区  · 8 年前

    我是Django的新手,我正试图通过 Category 模型。我在用外键 Product 对于类别。 这些是我的模型:

    class Category(models.Model):
        name = models.CharField(max_length=140)
        slug = models.SlugField(blank=True)
    
        def __str__(self):
            return self.name
    
        def get_absolute_url(self):
            return reverse("shop:category", kwargs= 
                    {"category_slug": self.slug})
    
    class Product(models.Model):
        category = models.ForeignKey(Category, 
                                   on_delete=models.CASCADE)
        brand = models.ForeignKey(Brand, 
                                   on_delete=models.CASCADE)
        title = models.CharField(max_length=200)
        slug = models.SlugField()
        description = models.TextField()
        image = models.ImageField(upload_to=image_name)
        price = models.PositiveIntegerField()
        avaliable = models.BooleanField(default=True)
    
        def get_absolute_url(self):
             return reverse("shop:product", kwargs={
                           "product_slug": self.slug,                                           
                           "product_ctgr_slug": 
                                       self.category.slug,})
    

    我的观点:

    class CategoryDetailView(DetailView):
        model = Category
        category_products = Category.product_set.all()
        slug_url_kwarg = "category_slug"
    
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context['categories'] = self.categories
            context['category_products'] = self.category_products
            return context
    

    AttributeError: 'ReverseManyToOneDescriptor' object has no attribute 'all' .

    2 回复  |  直到 8 年前
        1
  •  1
  •   cezar Dennis Kioko    8 年前

    你可以用 product_set 作为在Django中默认创建的相关名称,或者您最好自己创建一个相关名称。一个 属于 类别 ,但是 类别 可以有很多 产品

    为此,请为 category Product :

    category = models.ForeignKey(
        Category,
        on_delete=models.CASCADE,
        related_name='products'
    )
    

    现在在你的 views.py

    class CategoryDetailView(DetailView):
        model = Category
        # remove the line below
        category_products = Category.product_set.all()
        # don't prefix the fields like this, it's ugly and redundant
        # call it just slug, not category_slug, adjust in urls.py
        slug_url_kwarg = "category_slug"
    
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            # where did you get self.categories?
            context['categories'] = self.categories
            # and this won't work anymore too
            context['category_products'] = self.category_products
            return context
    

    CategoryDetailView 只显示一个类别。这是一个详细的视图-它只包含一个对象。所以你不会用 . 对象在方法中可用。我们就是这样重写的:

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        products = self.object.products.all()
        context['products'] = products
        return context
    
        2
  •  2
  •   Christo    8 年前

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        instance = self.get_object()
        context['categories'] = self.categories
        context['category_products'] = instance.product_set.all()
        return context