django 3在表单验证中使用pk重定向

django 3 redirect with pk in form verification

@MODS- 虽然在 Django 3 中找不到合适的答案之前已经在这里问过,但请在删除之前通读我尝试过的所有内容

序言: 我正在研究 Django 1 中教授的 This Tutorial,我正在关注它,但对 Django 3 进行了必要的更改。

问题: 我在加载带有表单的页面时收到错误消息。

HTML 表单页面:


{% block title %}Start a New Topic{% endblock %}

{% block breadcrumb %}
  <li class="breadcrumb-item"><a href="{% url 'home' %}">Boards</a></li>
  <li class="breadcrumb-item"><a href="{% url 'board_topics' board.pk %}">{{ board.name }}</a></li>
  <li class="breadcrumb-item active">New topic</li>
{% endblock %}

{% block content %}
  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" class="btn btn-success">Post</button>
  </form>
{% endblock %}

基础HTML:

{% block title %}Start a New Topic{% endblock %}

{% block breadcrumb %}
  <li class="breadcrumb-item"><a href="{% url 'home' %}">Boards</a></li>
  <li class="breadcrumb-item"><a href="{% url 'board_topics' board.pk %}">{{ board.name }}</a></li>
  <li class="breadcrumb-item active">New topic</li>
{% endblock %}

{% block content %}
  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" class="btn btn-success">Post</button>
  </form>
{% endblock %}

urls.py

from django.contrib import admin
from django.urls import path , re_path
#uses path and re_path for regex when needed.


from boards import views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('boards/(?P<pk>\d+)/$', views.board_topics, name='board_topics'),
    re_path('boards/(?P<pk>\d+)/new/$', views.new_topic, name='new_topic'),
    path('', views.home,name='home'),
]

Forms.py

from .models import Topic

class NewTopicForm(forms.ModelForm):
    message = forms.CharField(
        widget=forms.Textarea(
            attrs={'rows': 5, 'placeholder': 'What is on your mind?'}
        ),
        max_length=4000,
        help_text='The max length of the text is 4000.'
    )

    class Meta:
        model = Topic
        fields = ['subject', 'message']

views.py

from .models import Board, Topic, Post
from django.contrib.auth.models import User
from .forms import NewTopicForm
from django.http import HttpResponseRedirect

# Create your views here.
def home(request):
    boards = Board.objects.all()
    return render(request, 'home.html', {'boards': boards})

    
def board_topics(request, pk):
    try:
        board = Board.objects.get(pk=pk)
    except Board.DoesNotExist:
        raise Http404
    
    return render(request, 'topics.html', {'board': board})


def new_topic(request, pk):
    board = Board.objects.get(pk=pk)
    user = User.objects.first()  # TODO: get the currently logged in user

    if request.method == 'POST':
        form = NewTopicForm(request.POST)
        if form.is_valid():
            topic = form.save()
            return HttpResponseRedirect('/')

    else:
        form = NewTopicForm()
    return render(request, 'new_topic.html', {'form': form})

我认为我的问题来自 return HttpResponseRedirect('/').

在教程中他们使用重定向 return redirect('board_topics', pk=board.pk)

然而据我所知,这在 django 3 中是不可能的。另外,当我查看官方的 django 3.1 文档时,他们也使用了 HttpResponseRedirect。

我尝试过使用渲染器,但也无法使其工作。

有什么建议吗?我已经坚持了几个小时,想克服它。

尝试使用 reverse:

from django.shortcuts import reverse

... your form ...
return redirect(reverse('board_topics', kwargs={'pk': board.pk}))

顺便说一下,常规重定向应该也可以,试试吧。

编辑

您实际上需要在表单视图的上下文中将 board 作为参数传递:

 return render(request, 'new_topic.html', {'form': form, 'board': board})