【问题标题】:Decoupling django apps 2 - how to get object information from a slug in the URL解耦 django 应用程序 2 - 如何从 URL 中的 slug 获取对象信息
【发布时间】:2010-01-04 19:00:14
【问题描述】:

我正在尝试解耦两个应用程序:

  1. 位置 - 包含有关某些位置(城镇、国家、地点等)的详细信息的应用
  2. 目录 - 包含景点(商店、火车站、酒吧等)详细信息的应用 - 全部分类。

locations.Locationdirectory.Item 都包含 lat/lng 坐标,我可以在特定 lat/lng 坐标的一定距离内找到项目。

我想使用以下 URL 结构:

/locations/<location_slug>/directory/<category_slug>/

但我不想让我的目录应用依赖于我的位置应用。

如何翻译这个 url 以在我的目录应用程序中使用这样的视图?

items_near(lat, lng, distance, category):

一种解决方法是在某处创建一个新视图来翻译这个 - 但我应该把它放在哪里?如果它进入目录应用程序,那么我已经将它与我的位置应用程序结合起来,反之亦然。

将这个解决方法代码放在我的项目 URL 文件中是个好主意吗?从而避开这两个应用程序?这样做有什么问题吗?

【问题讨论】:

    标签: django django-urls decoupling


    【解决方案1】:

    要使您的 urlpattern 正常工作,调用的视图函数必须知道位置和目录。简短的回答是你可以把这个视图函数放在你想要的任何地方——它只是一个 python 函数。但是,在您的 Directory 或 Location 应用程序之外,它可能有一些合乎逻辑的地方是有意义的。

    首先,我不会将该视图代码放在您的顶级 urls.py 中,因为该文件用于 URLconf 相关代码。

    放置视图的几个选项:

    1. 在位于任何特定应用程序之外的文件中创建一个新的视图函数。 <project_root>/views.py 是一种可能性。这个视图从 Directory 应用调用 item_near(..) 视图没有任何问题。

      # in myproject/urls.py
      
      urlpatterns = (
         ...
         (r'/locations/(?P<location_slug>[\w\-]+)/directory/(?P<category_slug>[\w\-]+)/', 
          'myproject.views.items_near_from_slug')
      )
      
      # in myproject/views.py
      
      from directory.views import items_near
      
      def items_near_from_slug(request, location_slug, category_slug):
        location = get_object_or_404(Location, slug=location_slug)
      
        distance = 2 # not sure where this comes from
      
        # And then just invoke the view from your Directory app
        return items_near(request, location.lat, location.lng, distance, category_slug)
      
    2. 创建一个新应用并将代码放在那里,&lt;my_new_app&gt;/views.py。没有要求 Django 应用程序需要具有 models.py、urls.py 等。如果您希望 Django 正确加载应用程序,只需确保包含 __init__.py(例如,如果您希望 Django自动查找模板标签或应用特定模板)。

    就我个人而言,只有在项目相对简单的情况下,我才会选择选项 1,并且 &lt;project_root&gt;/views.py 不会有被所有视图混乱的危险。否则我会选择选项 2,特别是如果您预计有其他代码需要同时了解位置和目录。使用选项 2,您也可以在他们自己的应用程序特定 urls.py 中收集相关的 urlpatterns。

    【讨论】:

    • @zlovelady 我不知道可能有一个 url reverse() 问题......我从来没有机会使用这个功能,所以我从来没有见过这个陷阱
    • @JudoWill 在您的评论提到它之后,我编辑了“反向”陷阱,并进一步调查并意识到我错了。我正在考虑一个与 URLconf 和 reverse(..) 不同的问题,这与在小部件的媒体定义中使用 reverse(..) 有关。谢谢你提到它:)
    • 干杯 - 这似乎是将位置信息转换为 lng 和 lat 的最合乎逻辑的方式。这个地方应该在我的整个项目“应用程序”中 - 将它组合在一起的位......
    【解决方案2】:

    来自 django 文档 here 如果您使用的是 django >=1.1,那么您可以将任何捕获的信息传递到包含的应用程序中。所以拆分几个文件:

    # in locations.urls.py
    
    urlpatterns = ('',
      (r'location/(?P<location_slug>.*?)/', include('directory.urls')),
      #other stuff
      )
    
    
    # in directory.urls.py
    
    urlpatterns = ('',
      (r'directory/(?P<directory_slug>.*?)/', 'directory.views.someview'),
      #other stuff
      )
    
    # in directory.views.py
    
    def someview(request, location_slug = None, directory_slug = None):
     #do stuff
    

    希望对您有所帮助。如果你在 django

    【讨论】:

      【解决方案3】:

      无论您的应用程序有多少“可重复使用”,都不可避免地需要特定于站点的代码。

      我认为创建一个使用可重用和解耦应用程序视图的“特定于站点”的应用程序是合乎逻辑的。

      【讨论】:

        猜你喜欢
        • 2014-03-26
        • 2021-10-08
        • 1970-01-01
        • 2018-06-21
        • 1970-01-01
        • 2014-07-13
        • 1970-01-01
        • 2022-10-21
        • 1970-01-01
        相关资源
        最近更新 更多