python - Django - url 中的 View 或条件根据参数是否具有值或为 NONE 选择两种 url 模式之一

标签 python django django-views django-urls django-2.0

有两种模型:groupsposts。帖子可以是以下两种类型之一:分配给组,以及未分配给组。 posts 模型中的外键字段(将组分配给帖子)是可选的。属于某个群组的帖子应具有与不属于该群组的帖子不同的地址。这是一般规则。前一个地址是当帖子不属于任何组时的地址,而后一个地址是当帖子不属于任何组时的地址。

.../posts/[year]/[month]/[day]/[slug of the post]/

.../groups/[name of the group]/posts/[year]/[month]/[day]/[slug of the post]/

问题出现了。创建帖子后,两个 url 地址都有效。

这并不奇怪,因为我在 groupsurls.py包含来自 posts 应用程序的网址> 应用程序。

我想要做的是使 url 地址对于 group 参数是可选的(无论是否传递)。它可以像这样工作:

  • 如果 groups 参数不是 None,则从 groups.urls 中选择 url
  • 如果 groups 参数不是 None,则从 posts.urls 中排除 url

基本上我只想选择一个网址,而不是两个。

在 Django 中是否可以以简单的方式做到这一点?或者是创建两个模型/两个应用程序而不是一个的唯一解决方案?

我的代码摘录:

groups/urls.py

app_name = 'groups'

urlpatterns = [
    ...
    path('<slug:slug>/posts/', include('posts.urls', namespace='grouppost')),
    ...
]

posts/urls.py

app_name = 'posts'

urlpatterns = [
    path('', views.PostList.as_view(), name='list'),
    path('create', views.CreatePost.as_view(), name='create'),
    path('<int:year>/<int:month>/<int:day>/<slug:slug>/', views.PostDetail.as_view(), name='detail'),
    path('<int:year>/<int:month>/<int:day>/<slug:slug>/update/', views.UpdatePost.as_view(), name='update'),
    path('<int:year>/<int:month>/<int:day>/<slug:slug>/delete/', views.DeletePost.as_view(), name='delete'),
]

我使用的是 Django 2.0.7。

更新16.08

我还包含 mu root urls.py 中的路径。很抱歉遗漏了这一重要信息。

urls.py

urlpatterns = [
    ...
    path('groups/', include('groups.urls')),
    path('posts/', include('posts.urls')),
    ...
] 

最佳答案

您应该尽量避免网址中的逻辑。这就是更低级别的 View 或业务逻辑的用途。相反,您可以创建一个充当重定向页面的 View ,该页面接受您想要的参数,并根据参数内容重定向到正确的 url。

如果您这样做,您将需要跟踪所有请求参数。

# url (located wherever you want):
(r'post-redirection/<string:posts_or_group>/<int:year>/<int:month>/<int:day>/<slug:slug>/', post_redirection, name="post_redirection")

# view:
def post_redirection(request, post_or_group, year, month, day, slug):
    if post_or_group == "post":
         post_url_name = "..." # This is the url that you want to go to if it is a request to .../posts/[year]/[month]/[day]/[slug of the post]/
         return HttpResponseRedirect(reverse(post_url_name, kwargs={"year": year, "month": month, "day": day, "slug": slug}))

    elif post_or_group == "groups":
         group_url_name = "..." # This is the url that you want to go to if it is a request to .../groups/[name of the group]/posts/[year]/[month]/[day]/[slug of the post]/
         return HttpResponseRedirect(reverse(group_url_name, kwargs={"year": year, "month": month, "day": day, "slug": slug}))

    else:
        # error. However you want to handle it. You could return an error response or do something else. Maybe return a message that says they didn't choose the right option.

您可能遇到的唯一问题是保留请求数据(即 request.POST 或 request.GET)。您仍然可以使用这种方法,您只需要找到一种方法来在新的重定向请求中传递该数据,因为该数据仅持续一个请求。

关于python - Django - url 中的 View 或条件根据参数是否具有值或为 NONE 选择两种 url 模式之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51861600/

相关文章:

python - 使用 Python 在 Zebra 打印机上打印 XML

django - 覆盖 Django ModelForm 的 Clean_unique 方法

python - 为什么 ListView 不显示模板中的数据?

python - 在 python 中线程化 c++ 程序

python - 如何在 Python 中解析 YAML 文件

django - 如何从 HomePage(Page) 重定向到您的自定义应用程序模型

python - 用户表中的外键已保存但立即回滚

python - 导入错误: cannot import name widgets from django. contrib.admin

django - 将模型的实例传递给 django 表单集

python - 模式匹配检查大于符号前面是否没有小于符号