这一节我们将要给Rango项目设计两个表单:添加分类表单和添加页面表单。
14.Part2练习答案
我们先来创建about视图,编辑rango/views.py文件,在文件尾部加入如下内容:
rango/views.py:
def about(request):return render(request,'rango/about.html')
接下来在templates/rango文件夹下新建一个about.html文件,加入如下内容:
rangoproject/templates/rango/about.html:
<!DOCTYPE html><html><head><title>Rango</title></head><body><h1>关于Rango</h1>欢迎访问Rango!<br/>这是一张Rango的图片!<br/>{% load static %}<img src="{% static "rango.jpg" %}" alt="Rango" /></body></html>
随后编辑rango/urls.py文件,把urlpatterns部分变成这样:
rango/urls.py:
urlpatterns = patterns('', url(r'^$', views.index, name='index'), url(r'^category/(?P<category_name_slug>[\w\-]+)/$', views.category, name='category'), url(r'^about/$', views.about, name='about'), )
最后别忘了给index.html加上一个“关于”的链接,在</body>前插入这样一行代码:
rangoproject/templates/rango/index.html:
<a href="/rango/about/">关于</a><br/>
去浏览器里刷一下首页,看下效果吧!
15.创建分类表单
我们需要让用户可以提交页面和分类的信息,要完成这项功能,可以借助Django强大的表单处理功能。
首先在rango文件夹下创建一个forms.py文件,加入如下内容:
rango/forms.py:
from django import formsfrom rango.models import Page, Categoryclass CategoryForm(forms.ModelForm): name = forms.CharField(max_length=128, help_text="请输入分类名称:") views = forms.IntegerField(widget=forms.HiddenInput(), initial=0) likes = forms.IntegerField(widget=forms.HiddenInput(), initial=0) slug = forms.CharField(widget=forms.HiddenInput(), required=False)# 下面这个子类提供给表单一些额外的信息.class Meta:# 指定当前类关联到哪个模型,使用哪些字段model = Category fields = ('name',)class PageForm(forms.ModelForm): title = forms.CharField(max_length=128, help_text="请输入页面标题:") url = forms.URLField(max_length=200, help_text="请输入页面链接:") views = forms.IntegerField(widget=forms.HiddenInput(), initial=0)class Meta:# 指定关联到Page模型model = Page# 我们的表单中需要哪些字段?# 下面这个方法告诉我们,不需要选择每一个字段,# 有些字段允许使用空值,所以我们可以把它排除掉,# 比如说category字段,我们直接把它排除掉exclude = ('category',)#或者我们直接填写想要用到的字段(除了category字段),象下面这样写:#fields = ('title', 'url', 'views')
随后我们来创建一个叫add_category的视图,编辑rango/views.py 文件,先在文件头部插入一行代码:
rango/views.py:
from rango.forms import CategoryForm
再添加如下内容:
rango/views.py:
def add_category(request):# 检测是否用POST方法提交的if request.method == 'POST': form = CategoryForm(request.POST)# 提交的表单是否有效的?if form.is_valid():# 将这个新分类存入数据库.form.save(commit=True)# 调用index()视图.# 页面将跳转到首页.return index(request)else:# 若表单包含错误,则在终端显示错误信息.print(form.errors)else:# 如果不是用POST方法提交,则显示表单,供用户输入信息.form = CategoryForm()return render(request, 'rango/add_category.html', {'form': form})
接下来在templates/rango文件夹下新建一个add_category.html文件,加入如下内容:
rangoproject/templates/rango/add_category.html:
<!DOCTYPE html><html><head><title>Rango</title></head><body><h1>添加分类</h1><form id="category_form" method="post" action="/rango/add_category/">{% csrf_token %} {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %} {% for field in form.visible_fields %} {{ field.errors }} {{ field.help_text }} {{ field }} {% endfor %}<input type="submit" name="submit" value="创建分类" /></form></body></html>
然后编辑rango/urls.py文件,把urlpatterns部分变成这样:
rango/urls.py:
urlpatterns = patterns('', url(r'^$', views.index, name='index'), url(r'^category/(?P<category_name_slug>[\w\-]+)/$', views.category, name='category'), url(r'^about/$', views.about, name='about'), url(r'^add_category/$', views.add_category, name='add_category'), )
最后一步,让我们给index.html加上一个“添加分类”的链接,在</body>前插入这样一行代码:
rangoproject/templates/rango/index.html:
<a href="/rango/add_category/">添加分类</a><br />
看下效果,我们先在分类名称后面输入“emagic”,再点击”创建分类“按钮,程序会自动跳转回首页,你可以看到,”emagic”这个分类已经成功添加:
注意啊,如果你一次性添加多个分类,这些分类不一定会显示在首页上,因为我们对首页作了限制,最多只能显示5个分类。
Tips:关于中文分类名的添加
目前,当你添加中文分类名时,将无法正常访问对应的链接,这是由于slugify函数不能对中文名称进行别名处理,而且受Category模型的save函数限制,我们也无法在管理界面中手动修改别名。你可以这样做:
先修改Category模型的save函数,把它改为:
rango/models.py:
def save(self, *args, **kwargs):if slugify(self.name): self.slug = slugify(self.name) super(Category, self).save(*args, **kwargs)
就是加一个判断,只有在slugify(self.name)能将name转换时,才使用slugify转换过的别名,否则的话,使用你手工输入的别名。
改完模型后,当你在表单中输入中文分类时,只要在管理界面中手工修改别名,就可以让Rango支持中文分类名了。
16.创建页面表单
我们来添加一个叫add_page的视图,编辑rango/views.py 文件,先在文件头部插入一行代码:
rango/views.py:
from rango.forms import PageForm
再添加如下内容:
rango/views.py:
def add_page(request, category_name_slug):try: cat = Category.objects.get(slug=category_name_slug)except Category.DoesNotExist: cat = None if request.method == 'POST': form = PageForm(request.POST)if form.is_valid():if cat: page = form.save(commit=False) page.category = cat page.views = 0 page.save()# 页面跳转到这里更妥一些.return category(request, category_name_slug)else:print(form.errors)else: form = PageForm() context_dict = {'form':form, 'category': cat} return render(request, 'rango/add_page.html', context_dict)
接下来在templates/rango文件夹下新建一个add_page.html文件,加入如下内容:
rangoproject/templates/rango/add_page.html:
<!DOCTYPE html><html><head><title>Rango</title></head><body><h1>添加页面</h1> {% if not category_name_url %} The specified category does not exist!<br/>{% else %} <form id="page_form" method="post" action="/rango/category/`category_name_url`/add_page/"> {% csrf_token %} {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %} {% for field in form.visible_fields %} {{ field.errors }}<br/> {{ field.help_text}} {{ field }} {% endfor %} <br/> <input type="submit" name="submit" value="创建页面"/> </form>{% endif %} </body></html>
然后编辑rango/urls.py文件,把urlpatterns部分变成这样:
rango/urls.py:
urlpatterns = patterns('', url(r'^$', views.index, name='index'), url(r'^category/(?P<category_name_slug>[\w\-]+)/$', views.category, name='category'), url(r'^about/$', views.about, name='about'), url(r'^add_category/$', views.add_category, name='add_category'), url(r'^category/(?P<category_name_slug>\w+)/add_page/$', views.add_page, name='add_page'), )
最后一步,让我们给category.html加上一个“添加页面”的链接,在</body>前插入这样一行代码:
rangoproject/templates/rango/category.html:
<a href="/rango/category/{{ category_name_slug }}/add_page/">添加页面</a><br/>
这样,我们就把添加页面的表单做好了,你可以打开任意一个分类,点击“添加页面”的链接,就可以看到如下的效果:
【未完待续】
本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
作者:舍得
首发:舍得学苑@博客园