Django 网站有很多深入选项。如何有效地编写urls.py?

发布于 2024-08-19 23:45:14 字数 797 浏览 6 评论 0原文

我正在制作一个 django 网站来展示儿童服装。您从概览页面开始,您可以在其中看到包含所有衣服的列表。在侧栏中,您可以通过以下选项来优化您的搜索:

适合:

  • 男孩
  • 女孩

衣服材质:

  • 棉毛
  • 衣服

衣服尺码:

  • 56
  • 62
  • 68
  • 74
  • 80
  • 86
  • 92
  • 98
  • 104
  • 110
  • 116

衣服颜色:

  • 白色
  • 黑色
  • 红色
  • 绿色
  • 蓝色
  • 黄色

因此,假设用户对男孩服装感兴趣。她点击“boys”,然后在 URL websitename.com/clothes/boys/ 处获得 Clothes_boys 视图。该页面上的侧边栏列出了面料、尺寸和颜色的选项。然后,用户可以进一步深入到例如 /clothes/boys/cotton/56/white 以获得所有可用的 56 号白色棉质男孩衣服的列表。

我有正则表达式和对于上述场景的看法。但用户当然可以采用数百条不同的路径,例如 /clothes/red/wool/girls/92/ 等。

我如何去捕获所有这些不同的情况,而不必手动编写大量的正则表达式和视图。

I am making a django site to showcase children's clothing. You start with an overview page where you see a listing with all the clothes. In a side bar you have the following options to refine your search:

clothes for:

  • boys
  • girls

clothes in:

  • cotton
  • wool

clothes in size:

  • 56
  • 62
  • 68
  • 74
  • 80
  • 86
  • 92
  • 98
  • 104
  • 110
  • 116

clothes with the color:

  • white
  • black
  • red
  • green
  • blue
  • yellow

So, suppose the user is interested in boys clothes. She clicks on 'boys', and gets served the clothes_boys view at the URL websitename.com/clothes/boys/. On that page the sidebar lists the options for fabric, size and color. The user can then drill down further to for example /clothes/boys/cotton/56/white to get a listing of all the available white cotton boys' clothes in size 56.

I have the regexes and the views for the above scenario. But the user can off course take hunderds of different paths, like /clothes/red/wool/girls/92/ and so on.

How do I go about catching all those different cases without having to manually write each of those multitude of regexes and views.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

魔法少女 2024-08-26 23:45:14

解决方案 1:

使用 /gender/type/size/color/ 并为未指定的情况保留某种保留值 - 比如说 na。因此,如果用户首先单击“red”,他将转到 /na/na/na/red/。这样你只需要 1 个正则表达式,并且你的 url 是一致的。

解决方案 2:

为此使用 GET 参数。所有内容都在 url /clothes/ 中,但您可以指定 /clothes/?gender=boys&size=55&color=red 等。解析这些内容很容易视图中的值 (request.GET['gender'])。在此解决方案中,未指定的值只是未指定(就像我的示例中的类型)。

解决方案 3:

使用 Django-filter - 它是一个实现解决方案 2 的可插入应用程序。

Solution 1:

Use /gender/type/size/color/ and have some kind of reserved value for unspecified - let say na. so if the user first clicks "red", he'll go to /na/na/na/red/. This way you only need 1 regex, and your urls are consistent.

Solution 2:

use GET params for this. everything is in the url /clothes/, but you can specify /clothes/?gender=boys&size=55&color=red etc. It's easy enough to parse these values in the view (request.GET['gender']). In this solution, unspecified values are just unspecified (like type in my example).

Solution 3:

Use Django-filter - its a pluggable app that implements solution 2.

眉黛浅 2024-08-26 23:45:14

我对这个问题的第一反应是 中间件 解决方案与一些常见的 SEO 做法。由于 URL 架构中的选项范围相当狭窄,因此这可能是一个可行的选项。

中间件将负责对每个请求执行两个操作。

  1. 解析 request.path 查找您的网址片段。
  2. 创建特定于性别/尺寸/颜色/材质的 URL。

快速将某些东西组合在一起,它可能看起来像这样:

class ProductFilterMiddleware:
    GENDERS = ("girls", "boys")
    MATERIALS = ("cotton", "wool", "silk")
    def proc_url(self, path):
        """ Process a path looking for gender, color, material and size. """
        pieces = [x for x in path.split('/') if x != '']
        prod_details = {}
        for piece in pieces:
            if piece in self.GENDERS:
                prod_details['gender'] = piece
            elif piece in self.MATERIALS:
                prod_details['material'] = piece
            elif re.match(r'\d+', piece):
                prod_details['size'] = piece
            else:
                prod_details['color'] = piece
        return prod_details
    def get_url(self, prod_details):
        """ Parse the output of proc_url() to create the correct URL. """
        pieces = []
        if 'gender' in prod_details:
            pieces.append(prod_details['gender'])
        if 'material' in prod_details:
            pieces.append(prod_details['material'])
        if 'size' in prod_details:
            pieces.append(prod_details['size'])
        if 'color' in prod_details:
            pieces.append(prod_details['color'])
        return '/%s/' % '/'.join(pieces)
    def process_view(self, request, view_func, args, options):
        request.product_details = self.proc_url(request.path)
        request.product_url = self.get_url(request.product_details)

这将允许在您没有高级知识的情况下创建到您的产品的任意链接,从而使系统能够灵活地使用其 URL。这还包括部分 URL(只是尺寸和材质,显示所有颜色选择)。应顺利解析以下任何内容:

  • /56/cotton/red/boys/
  • /cotton/56/
  • /green/cotton/red/girls/
  • /cotton/

从这里,您的视图可以使用 request.product_details 作为指导创建要返回的产品列表。

此解决方案的第二部分是在您输出的每个页面。这应该可以防止重复内容对您的搜索引擎优化产生不利影响。

<link rel="canonical" href="http://www.example.com/{{ request.product_url }}" />

警告:Google 和其他搜索引擎可能仍会攻击您的网站,从它能找到的每个网址请求信息。这会很快给您的服务器带来严重的负载。由于内容可从许多不同的位置获得,因此蜘蛛可能会进行大量挖掘,即使它知道每个页面只有一个副本是真实的。

My first reaction to this problem would be a middleware solution combined with some common SEO practices. Because you have a fairly narrow field of options in your URL schema, this can be a viable option.

The middleware would be responsible for performing two actions on each request.

  1. Parse request.path looking for the pieces of your url.
  2. Create a URL that is specific for the gender/size/color/material.

Quickly hacking something together, it may look something like this:

class ProductFilterMiddleware:
    GENDERS = ("girls", "boys")
    MATERIALS = ("cotton", "wool", "silk")
    def proc_url(self, path):
        """ Process a path looking for gender, color, material and size. """
        pieces = [x for x in path.split('/') if x != '']
        prod_details = {}
        for piece in pieces:
            if piece in self.GENDERS:
                prod_details['gender'] = piece
            elif piece in self.MATERIALS:
                prod_details['material'] = piece
            elif re.match(r'\d+', piece):
                prod_details['size'] = piece
            else:
                prod_details['color'] = piece
        return prod_details
    def get_url(self, prod_details):
        """ Parse the output of proc_url() to create the correct URL. """
        pieces = []
        if 'gender' in prod_details:
            pieces.append(prod_details['gender'])
        if 'material' in prod_details:
            pieces.append(prod_details['material'])
        if 'size' in prod_details:
            pieces.append(prod_details['size'])
        if 'color' in prod_details:
            pieces.append(prod_details['color'])
        return '/%s/' % '/'.join(pieces)
    def process_view(self, request, view_func, args, options):
        request.product_details = self.proc_url(request.path)
        request.product_url = self.get_url(request.product_details)

This would allow arbitrary links to be created to your products without your advanced knowledge, allowing the system to be flexible with its URLs. This also includes partial URLs (just a size and material, show me all the color choices). Any of the following should be parsed without incident:

  • /56/cotton/red/boys/
  • /cotton/56/
  • /green/cotton/red/girls/
  • /cotton/

From here, your view can then create a list of products to return using request.product_details as its guide.

Part two of this solution is to then include canonical tags in each of the pages you output. This should prevent duplicate content from adversely affecting your SEO.

<link rel="canonical" href="http://www.example.com/{{ request.product_url }}" />

Warning: Google and other search engines may still hammer your site, requesting information from each URL that it can find. This can create a nasty load on your server very quickly. Because content is available from so many different locations, the spider may dig around quite a bit, even though it knows that only one copy of each page is the real deal.

┊风居住的梦幻卍 2024-08-26 23:45:14

像您指定的那样拥有多个路径的一个缺点是搜索引擎会将每个页面视为不同的排列 - 这可能会损害搜索引擎优化。

我还见过坏蜘蛛在这种情况下对站点进行本质上的 DOS 攻击。

这是一个令人讨厌的问题,通过实施尽可能最简单的解决方案可能会得到最好的解决。在我看来,Ofri 的第一个解决方案是,除了 NA 是一个丑陋的占位符。看起来更好的可能是“ALL_GENDERS”、“ALL_SIZES”、“ALL_TYPES”。这样,您就可以从 url 中获取信息,而不是让它看起来处于某种错误状态。

One disadvantage of having multiple paths like you've specified is that search engines are going to see each page as a distinct permutation - which might hurt SEO.

I've also seen bad spiders essentially DOS-attack a site in situations like this.

This is a yucky problem that you might be best served by implementing the simplest solution possible. To my eyes, Ofri's first solution is that, except NA is kind of an ugly placeholder. Something that'll look better to the eyes might be "ALL_GENDERS", "ALL_SIZES", "ALL_TYPES". That way, you can grok things from the url, instead of having it look like it's in some kind of error state.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文