【问题标题】:Get_Absolute_URL Reverse Slugs By Many To Many Field From Another Model in DjangoGet_Absolute_URL 从 Django 中的另一个模型中通过多对多字段反转 Slug
【发布时间】:2020-11-05 07:11:04
【问题描述】:

我使用 Slugs 来寻址 URL。一切正常,但是当我想显示产品详细信息时。 我不知道如何从另一个模型中获取两个 slug 并将其放在细节 slug 旁边。

(类别在主 URL 中)

(显示三星手机的所有产品)

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

(当我想点击其中一个时,我想要显示详细信息,但它不起作用)

不起作用site.com/category/mobile/samsung/s10

型号:

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)

当我使用这种相反的方式时,它给了我这个错误: “ForwardManyToOneDescriptor”对象没有属性“slug”

网址:

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'),
]

查看:

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)

【问题讨论】:

  • self.category.model.* 不是你想象的那样。删除 .model 部分,例如self.category.slug.
  • @Selcuk:当我从它们中删除模型时,它给了我这个错误:“'ManyRelatedManager' 对象没有属性 'slug'”
  • 哦,你有一个从产品到类别的多对多关系。在那种情况下self.category.slug 没有意义。 哪个类别?

标签: python python-3.x django django-models reverse


【解决方案1】:

我在从多对多关系的两个 slug 中返回绝对 url 时遇到了类似的问题,我的解决方案是返回对象的 url 集,如下所示。也许它会帮助其他人。

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 

【讨论】:

    【解决方案2】:

    您的数据结构有问题。

    您的产品模型有多个类别 (M2M)。 因此,当您要求 product.category 时,您不会得到单个类别,而是该产品的所有类别。 product.category 是一个查询集。

    您想从一组多个类别中获得一个 slug,每个类别都有不同的slug。这行不通。

    您有两种解决方案,具体取决于您要执行的操作。

    第一个是将M2M关系从产品到类别更改为ForeignKey frmo产品到类别。 这样,product.category 将为您提供 Category 模型实例,而不是 Queryset

    在这种情况下,您应该将 Product.category 字段重命名为 Product.categories,以明确您可以拥有多个类别。

    第二种解决方案:您必须从一组类别中选择一个类别。例如:

    slug = product.category.first().slug
    

    注意:如果没有与此产品关联的类别,first() 可能会返回 None。

    【讨论】:

    • 谢谢你的朋友,你的回答,我用了第二种方式,因为,我不必改变模型,加上太多的细节,现在它正在工作。但是我有一个问题,如果我们有两个以上的蛞蝓,我需要使用中间的一个,我还能用什么?我的意思是我们不能使用 first() 和 last(),因为我们需要中间的。
    • 另外,您能否解释一下第一个解决方案,我们如何使用 ForeignKey 来使用两个相关的类别?我的意思是,例如,iPhone7 是移动设备,也是苹果品牌。两大类。那么我们如何使用外键将这两个与iPhone7相关联。谢谢
    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2019-09-30
    • 2023-02-22
    • 1970-01-01
    • 1970-01-01
    • 2013-04-27
    • 2020-11-26
    相关资源
    最近更新 更多