简体   繁体   English

Get_Absolute_URL 从 Django 中的另一个模型的多对多字段反向 Slug

[英]Get_Absolute_URL Reverse Slugs By Many To Many Field From Another Model in Django

I use Slugs to address the URL.我使用 Slugs 来寻址 URL。 It all works but when I want to show product details.一切正常,但是当我想显示产品详细信息时。 I don't know how can I get two slugs from another model and put it beside the details slug.我不知道如何从另一个模型中获取两个 slug 并将其放在细节 slug 旁边。

(the category is in the main URL) (类别在主 URL 中)

(show me all products Samsung mobile) (向我展示三星手机的所有产品)

Works : site.com/category/mobile/samsung/作品site.com/category/mobile/samsung/

(I want when I want to click one of them, show me the details, but it doesn't work) (我想当我想单击其中一个时,向我显示详细信息,但它不起作用)

Doesn't Work : site.com/category/mobile/samsung/s10不工作site.com/category/mobile/samsung/s10

Model:模型:

from Django.db import models
from Django.shortcuts import reverse


class Category(models.Model):
    name = models.CharField(max_length=150)
    slug = models.SlugField(unique=True, max_length=200)
    child_category = models.ForeignKey('self', max_length=150, null=True, blank=True, on_delete=models.CASCADE)
    is_child = models.BooleanField(default=False)

    def get_absolute_url(self):
        return reverse('shop:brands', args=[self.slug])

    def get_absolute_url_product(self):
        return reverse('shop:products', args=[self.child_category.slug, self.slug])


class Product(models.Model):
    category = models.ManyToManyField(to=Category, related_name='products')
    name = models.CharField(max_length=150)
    slug = models.SlugField(unique=True, max_length=200)
    description = models.TextField()


# Here I did what I knew, but It didn't work.
===============================================

    def get_absolute_url_details(self):
        return reverse('shop:product_details', 
                       self.category.model.slug,
                       self.category.model.child_category.slug,
                       self.slug)

When I use this reverse way, it gives me this Error: 'ForwardManyToOneDescriptor' object has no attribute 'slug'当我使用这种反向方式时,它给了我这个错误: 'ForwardManyToOneDescriptor' object has no attribute 'slug'

URL:网址:

from Django.urls import path
from Shop import views

app_name = 'shop'

urlpatterns = [
    path('<slug:brands_slug>/', views.brands, name='brands'),
    path('<slug:brands_slug>/<slug:product_slug>/', views.products, name='products'),
    path('<slug:brands_slug>/<slug:product_slug>/<slug:product_details>/', views.details_products, name='product_details'),
]

View:看法:

def products(request, brands_slug, product_slug):
    product = Product.objects.filter(category__slug=product_slug, category__child_category__slug=brands_slug)
    context = {'product': product}
    return render(request, 'shop/products.html', context=context)


def details_products(request, brands_slug, product_slug, product_details):
    details = Product.objects.filter(category__child_category__slug=brands_slug, category__slug=product_slug, slug=product_details)
    context = {'details': details}
    return render(request, 'shop/product_details.html', context=context)

You have an issue with your datastructure.您的数据结构有问题。

Your Product model have multiple categories (M2M).您的产品型号有多个类别 (M2M)。 So, when your ask for product.category you don't get a single category, but all the categories this product is.因此,当您询问product.category 时,您不会得到单个类别,而是该产品的所有类别。 The product.category is a QuerySet. product.category是一个查询集。

You want to get one single slug out of a set of multiple categories, each with a different slug.您想从一组多个类别中获取一个slug,每个类别都有不同的 slug。 This cannot work.这是行不通的。

You have two solutions, depending on what you are trying to do.您有两种解决方案,具体取决于您要尝试做什么。

The first one is to change the M2M relation from product to category to a ForeignKey frmo product to category.第一个是将 M2M 关系从产品到类别更改为 ForeignKey frmo 产品到类别。 This way, product.category will give you a Category model instance instead of a Queryset .这样, product.category会给你一个Category模型实例而不是一个Queryset

In that case, you should rename the Product.category field to Product.categories to make it clear that you can have more than one category.在这种情况下,您应该将 Product.category 字段重命名为 Product.categories 以明确您可以拥有多个类别。

Second solution: you have to select one category from your set of categories.第二种解决方案:您必须从您的一组类别中选择一个类别。 For example:例如:

slug = product.category.first().slug

Beware: first() may return None if no categories are associated with this product.注意:如果没有与此产品相关联的类别,则first()可能会返回 None 。

I had a similar problem returning the absolute url from two slugs of a many-to-many relationship and my solution is to return the set of urls for the object as follows.我在从多对多关系的两个 slug 返回绝对 url 时遇到了类似的问题,我的解决方案是返回对象的 url 集,如下所示。 Maybe it will help other people.也许它会帮助其他人。

class Category(models.Model):
    ...
    slug = models.SlugField(max_length=255, blank=True, unique=True)
    ...

class Product(models.Model):
    ...
    slug = models.SlugField(max_length=255, blank=True, unique=True)
    categories = models.ManyToManyField(Category,
                                        related_name="categories",
                                        blank=True,
                                        )
    ...

    def get_absolute_urls(self):
        urls = []
        for category in self.categories.all():
            urls.append(f'/categories/{category.slug}/products/{self.slug}/')
        return urls 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM