Переадресация формы Django с использованием HttpResponseRedirect

Так что это не может быть слишком сложно, но я не могу понять это...

Мне нужна моя форма в django (находится в /file_upload/), чтобы загрузить файл, добавить его в базу данных и затем перенаправить на новую страницу, где параметр является идентификатором поля что я добавил в базу данных (расположен в /файле/163/, скажем).

Я установил urls.py, чтобы /file/163/ работал нормально, если вы перемещаетесь туда напрямую, но я не знаю, как туда добраться из файла /file/загрузки/.

Мой код выглядит так:

def add(request):
    if request.method == 'POST': # If the form has been submitted...
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            # do stuff & add to database
  my_file = FileField.objects.create()
            return HttpResponseRedirect(reverse('/file/', args=[my_file.id]))

Я не могу использовать это решение, потому что я не знаю, что будет с идентификатором поля, пока я не обработаю форму в views.py, поэтому перенаправление должно произойти в views.py. Я думаю.

Любые мысли?

Ответ 1

Ваше представление с формой должно выглядеть примерно так:

def add(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            # do stuff & add to database
            my_file = FileField.objects.create()
             # use my_file.pk or whatever attribute of FileField your id is based on
            return HttpResponseRedirect('/files/%i/' % my_file.pk)
    else:
        form = UploadFileForm()

    return render_to_response('upload_file.html', {
        'form': form,
    })

Ответ 2

У вас есть аргументы, чтобы reverse неверно в

return HttpResponseRedirect(reverse('/file/', args=[my_file.id]))

reverse принимает представление или имя или представление, а не URL.

Вы не говорите, что ваша функция просмотра вызывается для просмотра файла, но допустим, что она называется view, тогда выше должно быть

return HttpResponseRedirect(reverse('view', args=[my_file.id]))

или, может быть

return HttpResponseRedirect(reverse(view, args=[my_file.id]))

В зависимости от того, что именно вы написали в urls.py

Вы можете назвать имена в urls.py и использовать эти имена вместо функции names-, см. Документацию для большего количества примеров.

Использование реверса - хорошая идея, если вам нравится перетасовывать свой urls.py вокруг - вы сможете изменить любой из путей, и все ваши представления будут продолжать работать.

Ответ 3

Или вы можете просто использовать функцию redirect(to[, permanent=False], *args, **kwargs):

  • путем передачи объекта модели (если определен метод get_absolute_url модели), поэтому в вашем случае:

    my_file = FileField.objects.create()
    return redirect(my_file)
  • передав имя представления и некоторые аргументы positional и keyword, в вашем случае:

    my_file = FileField.objects.create()
    return redirect('file', my_file.pk)

    или используя позиционные аргументы, если это требует определение URL:

    my_file = FileField.objects.create()
    return redirect('file', file_id=my_file.pk)
  • путем передачи относительного, абсолютного или полного URL-адреса:
    my_file = FileField.objects.create()
    return redirect('/files/%i/' % my_file.pk)