【问题标题】:Django url path conflictDjango url路径冲突
【发布时间】:2021-03-09 15:21:11
【问题描述】:

我是 django 和 stackoverflow 的新手,所以我请求您的帮助,因为我不知道如何解决这个问题。

我正在做一个用于教育目的的电子商务网站。

我正在尝试实现这样的完整路径:

http://127.0.0.1:8000/category1/subcategory1/product1

或

http://127.0.0.1:8000/category2/subcategory2/subcategory3/product2

我想致电productlistview 列出任何类别的所有产品,并致电productdetailview 列出每个产品。

发生的情况是 django 总是调用 productlistview,即使我调用 url 'store:product_detail' 并得到 404 错误,因为它没有找到带有产品名称的类别。

我知道 django 总是停在第一个匹配的 url 中,但我授予 name 但它不起作用。

这是我的模板:

#index.html
{% recursetree menu_category %}
    <li>
        <a href="{% url 'store:product_list' cat_slug=node.full_slug %}">{{ node.name }}</a>
    {% if not node.is_leaf_node %}
        <ul class="children">
            {{ children }}
        </ul>
    {% endif %}
    </li>
{% endrecursetree %}


#product_list.html
{% for item in product %}
        <a href="{% url 'store:product_detail' cat_slug=category.full_slug prod_slug=item.slug %}"><p>{{ item.name }}</p></a>
{% endfor %}


#urls.py
app_name = 'store'
urlpatterns = [
    path('<path:cat_slug>', productlistview, name='product_list'),
    path('<path:cat_slug><slug:prod_slug>', productdetailview, name='product_detail'),
]

#views.py
def productlistview(request, cat_slug):
    category_select = get_object_or_404(Category, full_slug=cat_slug)
    product_list = Product.objects.filter(
        category__in=Category.objects.get(full_slug=cat_slug).get_descendants(include_self=True))
    return render(request, "store/product_list.html", {
        'category': category_select,
        'product': product_list,
    })


def productdetailview(request, prod_slug):
    product = get_object_or_404(Product, slug=prod_slug)
    return render(request, "store/product_detail.html", {
        'product': product,
    })


#models.py
class Category(MPTTModel):
    name = models.CharField(max_length=250)
    slug = models.SlugField(max_length=255, unique=True, blank=True, null=True, editable=False)
    full_slug = models.SlugField(max_length=255, unique=True, blank=True, null=True, editable=False)
    parent = TreeForeignKey("self", null=True, blank=True, related_name="children", on_delete=models.CASCADE)

    class MPTTMeta:
        order_insertion_by = ['name']

    def save(self, *args, **kwargs):
        value = self.name
        self.slug = defaultfilters.slugify(unidecode(value))
        self.full_slug = self.full_path()
        super().save(*args, **kwargs)

    def __str__(self) -> str:
        return self.name

    def full_path(self):
        full_path = ["/", self.slug]
        k = self.parent
        while k is not None:
            full_path.append('/')
            full_path.append(k.slug)
            k = k.parent
        return "".join(full_path[::-1])


class Product(models.Model):
    category = models.ManyToManyField(Category)
    name = models.CharField(max_length=150)
    slug = models.SlugField(max_length=255, unique=True, blank=True, null=True, editable=False)

    def save(self, *args, **kwargs):
        value = self.name
        self.slug = defaultfilters.slugify(unidecode(value))
        super().save(*args, **kwargs)

    def __str__(self) -> str:
        return self.name

提前感谢您抽出时间帮助我。

最好的问候

【问题讨论】:

    标签: django url path tags


    【解决方案1】:

    您的 urls.py 中似乎有错误。

    尝试改变:

    path('<path:cat_slug>', productlistview, name='product_list'),
    path('<path:cat_slug><slug:prod_slug>', productdetailview, name='product_detail'),
    

    到

    path('<path:cat_slug>/', productlistview, name='product_list'),
    path('<path:prod_slug>/', productdetailview, name='product_detail'),
    

    或仅使用 slug 尝试不同的方法,然后相应地更新您的视图

    # urls.py
    path('product-by-category/<slug:slug>/', productlistview, name='product_list'),
    path('product/<slug:slug>/', productdetailview, name='product_detail'),
    

    值得考虑将您的视图重构为基于类的视图。这可以帮助您编写更少的代码并保持更简洁。

    【讨论】:

    • 卡尔您好,感谢您的回复。如果我在 urls.py 中将 '' 更改为 /' 并将 '' 更改为 /' 它可以工作,但 url 只是 slug 和不是full_slug。当我改回路径时,总是会转到 productlistview。我不知道为什么它不起作用。最好的问候。
    • @pnsbf 我刚刚更新了我的答案,希望第二种方法可以解决问题。
    • 卡尔您好,非常感谢您的支持。我会尝试不同的方法。最好的问候。
    猜你喜欢
    • 2017-04-11
    • 2020-07-09
    • 1970-01-01
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-06
    • 2013-03-14
    相关资源
    最近更新 更多