TLDR:我希望能够在创建惰性对象之后在slug
reverse_lazy('view', kwargs={'slug':'my_page'})
中提供reverse_lazy('view').apply(kwargs={'slug':'my_page'})
。
我有以下url模式,其中包含一个用于标识页面模型实例的slug:
url(r'^(?P<slug>'+settings.SLUG_PATTERN+')/$', views.MyView.as_view(), name='view'),
我有另一个用于编辑页面的视图:
url(r'^(?P<slug>'+settings.SLUG_PATTERN+')/_edit/$',
views.MyEditView.as_view(success_url=reverse_lazy('view')), name='edit'),
请注意添加success_url
,以便在我提交包含新内容的表单时,我会重定向到现在编辑的页面。如果我更改了view
网址格式,我不必担心更新我的edit
网址的重定向。
在验证并保存表单后,该视图将获取要在HttpResponseRedirect
中使用的成功URL。但是,只有名称“视图”不足以识别URL。我还需要知道存储在我的页面模型的slug
字段中的slug名称。
类似的问题在这里:success_url in UpdateView, based on passed value
答案建议为每个视图编写自定义get_success_url
,但必须有更好的方法。
在django的edit.py的通用视图中,有以下内容:
url = self.success_url.format(**self.object.__dict__)
如果将success_url
作为硬编码网址提供,但使用诸如'{slug}/'
之类的slug标识符,则会将其替换为模型中的slug
字段。这与我想要的非常接近,但我不想硬编码我的URL。这让我想到了我的问题:
如何将参数传递给reverse_lazy
对象?我会在我的基本视图get_success_url
中使用self.object.__dict__
并且它只是工作无处不在。
此外,如果我的slug字符串存储在单独的Slug模型中,我可能希望成功URL为'{slug.name}/'
。通过上述方法,我可以提供URL参数和模型属性之间的映射:
redirect_model_mapping = {'slug': '{slug.name}'}
...
def get_success_url(self):
url = self.success_url
if is_a_lazy_redirect(url):
url = url.somehow_apply_parameters(redirect_model_mapping)
return url.format(**self.object.__dict__)
我希望somehow_apply_parameters
等同于最初调用reverse_lazy('blog:view', kwargs=redirect_model_mapping)
。但是我不认为这应该在urls.py
中,因为它不应该知道映射。
答案 0 :(得分:1)
这是一个黑客,但做我想要的......
class MyView(FormMixin, ...):
#this is actually set on child classes
redirect_model_mapping = {'slug':'{slug.name}'}
def get_success_url(self):
url = self.success_url
if url is not None:
if hasattr(self.success_url, '_proxy____kw'):
url_parameters = dict((k, v.format(**self.object.__dict__)) for k, v in six.iteritems(self.redirect_model_mapping))
url._proxy____kw = {'kwargs': url_parameters}
url = force_text(url)
else:
url = url.format(**self.object.__dict__)
else:
raise ImproperlyConfigured("No URL to redirect to.")
return url
它取代了通常传递给kwards
的{{1}}参数,但实际上它具有所需的值。由于reverse_lazy
也需要字符串匹配正则表达式,我必须首先在url参数和模型中的值之间进行映射。
我非常喜欢不需要写reverse_lazy
的方法。