Django - urls 中的视图或条件根据参数是否具有值或 NONE 选择两个 url 模式之一
Django - View or condition in urls chooses one of two url patterns with regard to whether the parameter has the value or is NONE
有两个模型:groups
和 posts
。 post 可以是以下两种之一:分配给组和未分配给组。 posts
模型中的外键字段,将组分配给 post,是可选的。属于一个组的 post 应该与不属于该组的地址具有不同的地址。这是一般规则。前一个地址是当 post 不属于任何组时的地址,而后一个地址是当它属于时的地址。
.../posts/[year]/[month]/[day]/[slug of the post]/
.../groups/[name of the group]/posts/[year]/[month]/[day]/[slug of the post]/
问题出现了。创建 post 后,两个 url 地址都可以工作。
这并不奇怪,因为我 include
来自 posts
应用程序的 groups
应用程序 urls.py
中的 urls
我想做的是使 url 地址相对于 group
参数可选(无论是否传递)。它可以像这样工作:
- 如果组参数不是 None,请从
groups.urls
中选择 url
- 如果组参数不是 None 从
posts.urls
中排除 url
基本上我只想选择一个url,而不是两个。
在Django中有没有可能用一种简单的方式来做呢?还是创建两个 models/two 应用程序而不是一个的唯一解决方案?
我的代码摘录:
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
我也include
mu root path
urls.py
。很抱歉遗漏了这一重要信息。
urls.py
urlpatterns = [
...
path('groups/', include('groups.urls')),
path('posts/', include('posts.urls')),
...
]
您应该尽量避免在 url 中出现逻辑。这就是更低级别的视图或业务逻辑的用途。相反,您可以创建一个视图作为重定向页面,该页面采用您想要的参数,并根据参数重定向到右侧 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)。您仍然可以使用这种方法,您只需要找到一种方法在新的重定向请求中传递该数据,因为该数据仅持续一个请求。
有两个模型:groups
和 posts
。 post 可以是以下两种之一:分配给组和未分配给组。 posts
模型中的外键字段,将组分配给 post,是可选的。属于一个组的 post 应该与不属于该组的地址具有不同的地址。这是一般规则。前一个地址是当 post 不属于任何组时的地址,而后一个地址是当它属于时的地址。
.../posts/[year]/[month]/[day]/[slug of the post]/
.../groups/[name of the group]/posts/[year]/[month]/[day]/[slug of the post]/
问题出现了。创建 post 后,两个 url 地址都可以工作。
这并不奇怪,因为我 include
来自 posts
应用程序的 groups
应用程序 urls.py
中的 urls
我想做的是使 url 地址相对于 group
参数可选(无论是否传递)。它可以像这样工作:
- 如果组参数不是 None,请从
groups.urls
中选择 url
- 如果组参数不是 None 从
posts.urls
中排除 url
基本上我只想选择一个url,而不是两个。
在Django中有没有可能用一种简单的方式来做呢?还是创建两个 models/two 应用程序而不是一个的唯一解决方案?
我的代码摘录:
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
我也include
mu root path
urls.py
。很抱歉遗漏了这一重要信息。
urls.py
urlpatterns = [
...
path('groups/', include('groups.urls')),
path('posts/', include('posts.urls')),
...
]
您应该尽量避免在 url 中出现逻辑。这就是更低级别的视图或业务逻辑的用途。相反,您可以创建一个视图作为重定向页面,该页面采用您想要的参数,并根据参数重定向到右侧 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)。您仍然可以使用这种方法,您只需要找到一种方法在新的重定向请求中传递该数据,因为该数据仅持续一个请求。