0

After a user updates a record and submits a POST request, what's the best way to redirect them to the previous page? I know there's a potential issue with using the HTTP_REFERER method however the user will be using not be using a browser with custom settings.

Example from the views.py - This does not work (it only refreshes the page)

class example(LoginRequiredMixin, UserPassesTestMixin, UpdateView):

    model = example
    template_name = 'storiesapp/example.html'
    fields = ['title']

    def form_valid(self, form):
        form.instance.fk_user = self.request.user
        form.save()
        return HttpResponseRedirect(self.request.META.get('HTTP_REFERER'))
    
    def test_func(self):
        post = self.get_object()
        if self.request.user == post.fk_user:
            return True
        return False

If I remove 'self', I receive a PK expected error, if I add a PK, i'm directed immediately to my profile

.

.

I've tried the below, but recieve an error

This allows me to click through to edit the data but upon saving to update, it gives me an error that it expects a PK. If I change the def post to (self, request, pk) - when clicking on the record to update it takes me immediately to my profile instead of the template that allows me to update in the first place.

class pictures_update (LoginRequiredMixin, UserPassesTestMixin, UpdateView):

model = pictures
fields = ['name', 'date']
template_name = 'storiesapp/pictures.html'


def form_valid(self, form):
    form.instance.fk_user = self.request.user
    form.save()


def get(self, request):
    next_url = request.POST.get('next') if 'next' in request.POST else 'profile'
    return redirect(next_url)

def test_func(self):
    post = self.get_object()
    if self.request.user == post.fk_user:
        return True
    return False

.

.

If I combine the first two together, it only allows 2 arguments to be passed, whichever is listed third is ignored and causes an error. In this example, it tells me 'form' was expected.

def form_valid(self, request, form):
    next_url = request.POST.get('next') if 'next' in request.POST else 'profile'
    form.instance.fk_user = self.request.user
    form.save()
    return redirect(next_url)

1 Answers1

1

I tend to use the following, where I send the redirect url as part of the POST request from the page that called it. I store this in 'next':

from django.shortcuts import redirect
...
next_url = request.POST.get('next') if 'next' in request.POST else 'profile'
return redirect(next_url)

A good explanation of a potential implentation can be found here: How to redirect to previous page in Django after POST request. But you can add the 'next' to your POST request however you wish.

Here is an example of how I would implement this in a view:

class TestView(View):
    template_name = "sample/template.html"

    def get(self, request):
        next_url = request.GET.get('next')
        form = TestForm()
        ...
        return render(request, template_name=self.template_name, context={'form': form, "next": next_url})
        return redirect(next_url)

    def post(self, request):
        form = TestForm(request.POST)
        next_url = request.POST.get('next')
        ...
        return redirect(next_url)
figbar
  • 714
  • 12
  • 35
  • Where would I place this if i'm not using forms? Under the appropriate view? This is where the example in my question comes from, i'll update my answer to make it clearer. – Game Analysis Aug 10 '21 at 12:39
  • Yes, in your view at the end of your post request instead of whatever hard coded or broken return url you are currently using. – figbar Aug 10 '21 at 20:06
  • I have a 'request not defined error', please see my question for the code I tried – Game Analysis Aug 12 '21 at 23:59
  • put it in a post request function in your class: `def post(self, request):` That will get called on a post request and provide a request object – figbar Aug 13 '21 at 20:36
  • Still getting an error, i've updated my question to explain what these are. – Game Analysis Aug 14 '21 at 11:36
  • I added an example of how I would put it in a view. Note that you neet .GET if in a get request, and .POST if in a post request, you seem to be mismatching a bit – figbar Aug 15 '21 at 19:32
  • Thanks for all the help, i tried placing the code above the test_func, and am getting a 'get() got an unexpected keyword argument 'pk''. I'm still learning so there's obviously something I'm getting wrong. – Game Analysis Aug 15 '21 at 20:43
  • Then try adding pk back as an argument to get/post so it knows to look for the argument. – figbar Aug 15 '21 at 21:06