简体   繁体   中英

Best practice/help to redirect in Django after form submit

Django noob here, don't quite understand the concepts, so not able to get any help from similar questions from StackOverflow.

I have a form with only one dropdown, if the submit is pressed the value of the dropdown should be forwarded to the next page. So that the content is customised depending on the drop-down.

How does one redirect, after the post to the next page with arguments? is it even correct to use "HttpResponseRedirect(reverse"?

views.py

def appStart(request, institution):
    #so something with institution
    return render(request, 'application/SectionStart.html', {'content':{'if you would like to contact me emial','email@email.com'}})

def ReviewMyView(request):
    form_class = ApplicationSelectInstituation
    if request.method == 'POST':
         form = form_class(data=request.POST)
         if form.is_valid():
             for field, value in form.cleaned_data.items():
                 return HttpResponseRedirect(reverse('appStart', args=(value,)))
                 #return HttpResponseRedirect(reverse('view_blog', args=(), kwargs={'institution': value}))
                 #return HttpResponseRedirect(reverse('appStart'), {'institution': value})
                 #return HttpResponseRedirect(reverse('appStart'), institution=value)

    return render(request, 'application/appmyreview.html', {
        'form': form_class
    })

urls.py

urlpatterns = [
url(r'^xxx/(?P<institution>\d+)$', appStart, name='appStart'),
url(r'^myapp$', ReviewMyView, name='review'),
]

Update

Thank you for the answers, think I need to readup on the Django basics as I am not getting it.

def my_awesome_django_view(request):
    form_class = ApplicationSelectInstituation

    if request.method == "POST":
        form = ApplicationSelectInstituation(data=request.POST)
        if form.is_valid():
            content_data = form.cleaned_data.get('institution_name').id
            #Try 1 - page just refreshes
            #redirect("nextapppage/"+str(content_data))
            #Try 2 - Reverse for 'next_view' with arguments '()' and keyword arguments '{'institution_id': 3}' not found. 0 pattern(s) tried: []
            #return HttpResponseRedirect(reverse('next_view',kwargs={'institution_id': content_data}))
            #Try 3 - Reverse for 'next_view' with arguments '(3,)' and keyword arguments '{}' not found. 0 pattern(s) tried: []
            return HttpResponseRedirect(reverse('next_view', args=[content_data]))

    return render(request, 'application/appmyreview.html', {
        'form': form_class
    })

def the_next_view(request, *args, **kwargs):
    print("I got to: the_next_view")
    return render(request, 'application/SectionStart.html', {'content':{'if you would like to contact me emial','email@email.com'}})

urls.py

urlpatterns = [
url(r'^myapp$', my_awesome_django_view, name='myapp'),
url(r'^nextapppage/(?P<institution_id>\d+)/$', the_next_view, name='the_next_view'),

You should probably use HttpResponseRedirect in concert with reverse.

You can provide parameters to reverse with the args argument. So in your view:

def my_awesome_django_view(request):
    # some get method stuff
    if request.method == "POST":
        form = MyForm(data=request.POST)
        if form.is_valid():
            content_data = form.cleaned_data.get('my_field')
            return HttpResponseRedirect(reverse('next_view', args=[content_data]))

In the next view:

def the_next_view(request, *args, **kwargs):
    content = content_getter(*args)
    return HttpResponse(content)

In the urlconf you just wouldn't use named parameters in the regex but I would use a named parameter for clarity and explicitness so in 2 months when you're trying to figure out why you wrote this you'll be able to give yourself some breadcrumbs (learned that the hard way too many times).

With kwargs you just pass it in like so:

reverse('my_view_name', kwargs={'my_kwarg': value})

Just for completeness:

urlpatterns = [
    url(r'^xxx/(?P<institution>[\d]+)$', the_next_view, name='appStart'),
    url(r'^myapp$', my_awesome_django_view, name='review'),
]

Also note that I've altered the regex in the urlconf.

Have you considered using class-based views ? They are very simple to use, most of basic functionality is already made for you, packed with intuitive names and great documentation.

from django.views.generic.edit import FormView

class MyFormView(FormView):
    template_name = 'my_template.html'
    form_class = MyForm

    def form_valid(self, form):
        # on successful form submit
        self.next_url = reverse('appStart', args=[form.some_value])
        return super().form_valid(form)

    def get_success_url(self):
        return self.next_url

in urls.py

url(r'^myapp$', MyFormView.as_view(), name='review'),

If your view needs to lead to another view that will then provide a response to the browser, why not use the shortcut redirect ?

from django.shortcuts import redirect

def ReviewMyView(requst):
    if request.method == 'POST':
        # do stuff...
        redrect(appStart, form.cleaned_data[?])

You can pass whatever parameters the next view requires.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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