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

时间:2010-02-01 01:51:53

标签: django django-urls

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

衣服:

  • 男孩
  • 女孩
衣服在:

  • 羊毛

衣服尺寸:

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

颜色的衣服:

  • 红色
  • 绿色
  • 蓝色
  • 黄色

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

我有上述场景的正则表达式和视图。但是用户可以偏离不同的路径,例如/clothes/red/wool/girls/92/等等。

如何在不必手动编写大量正则表达式和视图的情况下捕获所有这些不同的案例。

3 个答案:

答案 0 :(得分:3)

解决方案1:

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

解决方案2:

为此使用GET参数。一切都在网址/clothes/中,但您可以指定/clothes/?gender=boys&size=55&color=red等。在视图中解析这些值很简单(request.GET['gender'])。在此解决方案中,未指定的值是未指定的(如我的示例中的类型)。

解决方案3:

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

答案 1 :(得分:2)

我对此问题的第一反应是middleware解决方案与一些常见的SEO实践相结合。因为您在URL架构中有一个相当狭窄的选项字段,所以这是一个可行的选择。

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

  1. 解析request.path寻找您的网址。
  2. 创建特定于性别/尺寸/颜色/材料的网址。
  3. 快速黑客攻击,可能看起来像这样:

    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作为指南返回的产品列表。

    此解决方案的第二部分是在您输出的每个页面中包含canonical tags。这可以防止重复内容对您的SEO产生负面影响。

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

    警告:Google和其他搜索引擎可能仍会破坏您的网站,从其可以找到的每个网址请求信息。这可能会很快在您的服务器上产生令人讨厌的负载。因为内容可以从很多不同的位置获得,所以蜘蛛可能会挖掘很多,即使它知道每页只有一个副本是真正的交易。

答案 2 :(得分:1)

像你指定的那样拥有多条路径的一个缺点是,搜索引擎会将每个页面看作一个独特的排列 - 这可能会损害搜索引擎优化。

我也看到过糟糕的蜘蛛在这种情况下基本上是DOS攻击一个网站。

这是一个令人讨厌的问题,您可以通过实施最简单的解决方案来获得最佳服务。对我来说,Ofri的第一个解决方案是,除了NA是一个丑陋的占位符。对眼睛看起来更好的东西可能是“ALL_GENDERS”,“ALL_SIZES”,“ALL_TYPES”。这样,您可以从网址中查找内容,而不是让它看起来像某种错误状态。