【发布时间】:2016-01-11 23:06:51
【问题描述】:
这是我的更新视图,由带有 slug 字段的 URL 调用,例如
/mymodel/update/<model_name_slug>/
MyModel 有两个字段,name 和 slug。 slug 字段<model_name_slug> 是从MyModel.name 自动生成的。如果用户更新它,将自动生成一个新的 slug 字段。然后,我想使用新生成的 slug 字段重定向到这个新 URL。
slug 字段自动生成正在工作。它在MyModelEditForm 中实现。但是,下面的代码将不起作用。原因是:
1) 用户输入此 URL 以更新现有模型
/mymodel/update/example-model
2) 用户将 Name 属性更改为 "example model changed"。然后 slug 字段将在MyModel 中生成为"example-model-changed"。
3) 但是 URL 没有重定向到 "/mymodel/update/example-model-changed",因为 get_object() 将返回 None. get() 将无法将新生成的 URL "example-model-changed" 与原始 "example-model" 进行比较
我在下面的代码中缺少什么?我尝试使用self.object 访问新更新的对象,但出现以下错误:
MyModelUpdateView object has no attribute 'object'
这里是sn-p的代码:
class MyModelUpdateView(LoginRequiredMixin, UpdateView):
model = MyModel
form_class = MyModelUpdateForm
template_name = 'mymodel/update_mymodel.html'
def get_success_url(self):
view_name = 'update_mymodel'
return reverse_lazy(view_name, kwargs={'model_name_slug': self.kwargs.get('model_name_slug','')})
def get_form_kwargs(self):
'''
This injects form with keyword arguments.
'''
kwargs = super(MyModelUpdateView, self).get_form_kwargs()
#Update the kwargs with the user_id
kwargs['user'] = self.request.user
return kwargs
def get(self, request, *args, **kwargs):
# self.object = self.get_object()
if self.request.path != self.object.get_absolute_url():
return HttpResponseRedirect(self.object.get_absolute_url())
else:
return super(MyModelUpdateView, self).get(request,*args, **kwargs)
# context = self.get_context_data(object=self.object)
# return self.render_to_response(context)
def get_object(self, queryset=None):
instance = MyModel.objects.get(slug=self.kwargs.get('model_name_slug',''))
return instance
即使正确更新了 get_success_url(),get_object() 似乎也有两个相互冲突的要求: 1) 能够使用现有的“example-model” slug 字段获取正确的对象; 2) 能够在现有 URL 未重定向之前使用新生成的“example-model-changed”获取更新的对象。
【问题讨论】:
-
顺便说一句,我认为如果您在视图上设置
slug_url_kwarg = 'model_name_slug',您将不必覆盖get_object方法。 -
你的意思是slug_url_kwarg会自动成为get_success_url中新生成的slug字段吗?
-
不,这与在
get_success_url中获取蛞蝓是分开的 - 为此,请参阅下面的答案。您已覆盖get_object,但您不必这样做,只需将slug_url_kwarg = 'model_name_slug'设置为类属性即可。 -
谢谢。我会试一试,让你知道。顺便说一句,我想出了另一种方法来做到这一点,并将其发布在下面
标签: django django-forms django-views django-generic-views