首页 > 解决方案 > 使用 html 表单在 django 中呈现页面

问题描述

我有这两个功能,其中一个(第一个)添加一个新条目,第二个编辑条目:

def add_entry(request):
    if request.method == 'POST':
        form = AddForm(request.POST)
        if form.is_valid():
            title = form.cleaned_data["title"]
            content = form.cleaned_data["content"]
            if util.get_entry(title) is None:
                util.save_entry(title, content)
                return redirect('entry', title)
            else:
                return render(request, "encyclopedia/add_entry.html", {
                    "form": AddForm(),
                    "title": title
                })

    return render(request, "encyclopedia/add_entry.html", {
        "form": AddForm()
    })


def edit_entry(request, title):
    content = util.get_entry(title)
    if request.method == 'POST':
        form = AddForm(request.POST)
        if form.is_valid():
            title = form.cleaned_data["title"]
            content = form.cleaned_data["content"]
            util.save_entry(title, content)
            return redirect('entry', title)

    return render(request, "encyclopedia/edit_entry.html", {
        "title": title,
        "content": content

这是我的 edit_entry.html 页面:

{% extends "encyclopedia/layout.html" %}

{% block title %}
    Edit page
{% endblock %}

{% block body %}
<form action="{% url 'edit_entry' title %}" method="POST">
    {% csrf_token %}
    <h5>Title</h5>
    <input type="text" value="{{ title }}">
    <h5>Content</h5>
    <textarea cols="30" rows="10">{{ content }}</textarea>
    <input type="submit" value="Save Editing">
</form>
{% endblock %}

这是 add_entry.html 模板

{% extends "encyclopedia/layout.html" %}

{% block title %}
    Add new entry
{% endblock %}

{% block body %}
    <h1>Create a new page</h1>
    {% if title %}
        <h6 style="color: red;">"{{title}}" page is already exists. Please, enter a different title</h6>
    {% endif %}
<form action="{% url 'add_entry' %}" method="POST">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Create">
</form>
{% endblock %}

这是我的 urls.py:从 django.urls 导入路径

from . import views

urlpatterns = [
    path("", views.index, name="index"),
    path("wiki/<str:title>", views.entry, name="entry"),
    path("search", views.search, name="search"),
    path("add_entry", views.add_entry, name="add_entry"),
    path("wiki/<str:title>/edit_entry", views.edit_entry, name="edit_entry")
]

我的入口视图:

def entry(request, title):
    if title not in util.list_entries():
        return render(request, "encyclopedia/error.html", {
            "error": "Page Not Found",
            "query": title
        })
    else:
        return render(request, "encyclopedia/entry.html", {
            "entry": markdown2.markdown(util.get_entry(title)),
            "title": title
        })

当我点击保存页面内容时这里的问题没有改变,我想保存编辑并用新内容显示它。相反,它返回一个带有旧内容的旧表单(就像没有改变一样)。

标签: djangodjango-formsdjango-templates

解决方案


编辑:根据您的评论,我认为最好重新开始。由于您正在进行一些简单的创建和更新,因此使用通用视图可能会更好。这是一个例子。

1.首先,你需要一个模型。

在models.py中,

from django.db import models

class Entry(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField(max_length=2000)

2. 在你的 forms.py 注意:如果你只想使用 django 默认表单,这不是必需的。因为基于类的通用视图会自动为您生成表单。但是,如果您需要添加widget,或者添加属性(例如,添加css 类或id),则需要生成自定义表单。

from django import forms
from .models import Entry

class EntryForm(forms.ModelForm):
        class Meta:
        model = Entry
        fields = ('title', 'content')
        widgets = {
            'title': forms.TextInput(attrs={'placeholder': 'Title'}),
            'content': forms.TextInput(attrs={'class': 'content'}),
        }

3.views.py

from .models import Entry
from django.views.generic.edit import CreateView, UpdateView

class CreateEntry(CreateView):
    model=Entry
    template_name = 'create_edit_entry.html' # this is the template, you might need to change its path.

    form_class= EntryForm # this is added because we are using customform

    success_url = '/' #this can be changed

class UpdateEntry(UpdateView):
    model=Entry
    template_name = 'create_edit_entry.html'

    form_class= EntryForm

4.urls.py

from django.urls import path
from .views import CreateEntry, UpdateEntry

urlpatterns = [
    path('entry/', CreateEntry.as_view(), name='create_entry'),
    path('entry/<int:pk>', UpdateEntry.as_view(), name='update_entry'),

]

5. 管理员.py

from django.contrib import admin
from .models import Entry

class EntryAdmin(admin.ModelAdmin):
    list_display = (('id', 'title', 'content'))

admin.site.register(Entry, EntryAdmin)

6. 模板(create_edit_entry.html)

{% extends 'base.html' %}

{% block extrahead %} 
{% load static %}
  
{% endblock %}

{% block content %}
<form action="." method="POST">
    {% csrf_token %}
    {{ form }}
    <button type="submit">SUBMIT</button>

</form>
{% endblock %}

更新所有这些文件并更新 mysite/urls.py 后,您将 1) 打开http://127.0.0.1:8000/entry以添加一个条目。检查是否在您的管理页面中创建了该条目。2)然后您将打开http://127.0.0.1:8000/entry/1(如果 id=1)以查看是否显示了您的原始条目。3)然后您将更新表单,并在您的管理员中检查更新是否成功。

这个骨干应该能够让你开始。注意,我没有放DetailView,ListView,所以你需要在你的admin页面中检查对象是否被创建和更新。当然,您可以自己添加 DetailView 和 ListView (在此处查看 django 文档以了解有关通用视图的更多信息)。

******************************************前面的回答********** ****

1.首先,当您遇到表单问题时,访问 form.errors 总是有帮助的。您要做的是添加 else: print(form.errors)如下内容:

if form.is_valid():
     # other code

else:
     print(form.errors)

2.edit_entry.html对以下内容的更改:我猜您想在表单中使用自己的样式(添加标题、内容等),所以您没有使用 {{form}}。如果我的建议有效,您可以稍后添加表单样式。

{% extends "encyclopedia/layout.html" %}

{% block title %}
    Edit page
{% endblock %}

{% block body %}
<form action="{% url 'edit_entry' title %}" method="POST">
    {% csrf_token %}
    {{form}}
</form>
{% endblock %}

3.您的edit_entry看法:

def edit_entry(request, title):
    entry = get_object_or_404(Entry, title=title) # i assume your Model name is "Entry"
    if request.method == 'POST':
        form = AddForm(request.POST, instance = entry)
        if form.is_valid():
            print('under form.is_valid) # add this line to keep track
            title = form.cleaned_data["title"]
            content = form.cleaned_data["content"]
            form.save()
            return redirect('entry', title=entry.title)
         else:
             print(form.errors)

    else:
        form = AddForm(instance = entry)

    return render(request, "encyclopedia/edit_entry.html", {
        'form': form})

推荐阅读