简体   繁体   English

Django Generic查看UpdateView重定向URL和更新的slug

[英]Django Generic View UpdateView redirect URL with updated slug

This is my updateview which is called by a URL with slug field, eg 这是我的更新视图,由具有slug字段的URL调用,例如

/mymodel/update/<model_name_slug>/

MyModel have two fields, name and slug . MyModel有两个字段, nameslug The slug field <model_name_slug> is automatically generated from MyModel.name . slug字段<model_name_slug>是从MyModel.name自动生成的。 If the user update it, a new slug field will be automatically generated. 如果用户更新它,将自动生成一个新的段塞字段。 Then, I want to redirect to this new URL with the newly generated slug field. 然后,我想用新生成的slug字段重定向到这个新URL。

The slug field auto-generation is working. 段塞场自动生成正在运行。 It is implemented in the MyModelEditForm . 它在MyModelEditForm实现。 However, the code below won't work. 但是,下面的代码不起作用。 The reason is: 原因是:

1) User typed this URL to update the existing model 1)用户键入此URL以更新现有模型

/mymodel/update/example-model

2) User changes the Name attribute to "example model changed" . 2)用户将Name属性更改为"example model changed" Then slug field will be generated as "example-model-changed" in MyModel . 然后将在MyModel生成slug字段作为"example-model-changed"

3) But the URL is not redirected to the "/mymodel/update/example-model-changed" , as get_object() will return None. get() 3)但是URL没有重定向到"/mymodel/update/example-model-changed" ,因为get_object()将返回None. get() None. get() will not be able to compare the newly generated URL "example-model-changed" with original "example-model" None. get()将无法将新生成的URL "example-model-changed"与原始"example-model"

What am I missing in below code? 我在下面的代码中缺少什么? I tried to access the newly update object using self.object , but have following error: 我尝试使用self.object访问新的更新对象,但有以下错误:

 MyModelUpdateView object has no attribute 'object'

Here is the code snippet: 这是代码片段:

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

Even if the get_success_url() is correctly updated, the get_object() seems to have two conflicting requirements: 1) Be able to fetch the correct object using existing "example-model" slug field; 即使get_success_url()被正确更新,get_object()似乎也有两个相互矛盾的要求:1)能够使用现有的“example-model”slug字段获取正确的对象; 2) Be able to fetch the updated object using newly generated "example-model-changed" before the existing URL is not redirected. 2)能够在未重定向现有URL之前使用新生成的“example-model-changed”获取更新的对象。

You don't have to use self.get_object in the get_success_url method. 您不必在get_success_url方法中使用self.get_object The form_valid() sets self.object when saving the form, so you can use self.object.slug to get the new url. form_valid()在保存表单时设置self.object ,因此您可以使用self.object.slug来获取新的url。

def get_success_url(self):
    view_name = 'update_mymodel'
    # No need for reverse_lazy here, because it's called inside the method
    return reverse(view_name, kwargs={'model_name_slug': self.object.slug})

Haven't used class based view much, but.. 没多少使用基于类的视图,但..

def get_success_url(self):
        view_name = 'update_mymodel'
        return reverse_lazy(view_name, kwargs={'model_name_slug': self.kwargs.get('model_name_slug','')})

If get_success_url is supposed to return the url that you want to redirect user to, shouldn't you use the updated slug not the old one? 如果get_success_url应该返回你要将用户重定向到的url,那么你不应该使用更新的slug而不是旧的slug吗?

self.get_object().model_name_slug

I guess this is correctly done atm. 我想这是正确完成的。

1) Be able to fetch the correct object using existing "example-model" slug field; 1)能够使用现有的“example-model”slug字段获取正确的对象;

You want to get the updated url based on updated model for redirect. 您希望根据更新的重定向模型获取更新的URL。 Where do you create the updated url? 你在哪里创建更新的网址? get_success_url?. get_success_url? Then I don't see why reverse_lazy(view_name, kwargs={'model_name_slug': self.get_object().model_name_slug}) doesn't work? 然后我不明白为什么reverse_lazy(view_name, kwargs={'model_name_slug': self.get_object().model_name_slug})不起作用?

2) Be able to fetch the updated object using newly generated "example-model-changed" before the existing URL is not redirected. 2)能够在未重定向现有URL之前使用新生成的“example-model-changed”获取更新的对象。

Thank Alasdair and eugene for the quick help. 感谢Alasdair和eugene的快速帮助。

Meanwhile, I have figured out another way to do this! 与此同时,我已经想出了另一种方法! That is, use two arguments in the URL, like and . 也就是说,在URL中使用两个参数,例如和。

Look up in the stackoverflow URL. 在stackoverflow URL中查找。 Have you noticed something similar? 你有没有发现类似的东西? Yes, that is it. 是的,就是这样。 33115530 is the pk, I guess. 我想是33115530是pk。 The rest is slug field automatically generated! 其余的是slug字段自动生成!

Then, in get_object, the newly updated object will be fetched through the , and get_success_url can use the new slug field updated in the object. 然后,在get_object中,将通过get_success_url获取新更新的对象,并且get_success_url可以使用在对象中更新的新slug字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM