Django表单与视图开发全解析
立即解锁
发布时间: 2025-08-22 01:25:45 阅读量: 1 订阅数: 2 


Django Web开发实战秘籍
### Django表单与视图开发全解析
#### 1. 表单字段与视图基础
在开发中,除了常规字段,我们还能传递HTML片段,例如在图像字段的帮助块中就可以这样操作。同时,在布局里可以使用前置文本字段,像给电话字段添加电话图标,给邮箱字段添加@符号。借助Div对象,能轻松将字段包装进HTML的`<div>`元素,这在需要对某些表单字段应用特定JavaScript时非常有用。
HTML表单的`action`属性由表单助手的`form_action`属性定义,`method`属性由`form_method`属性定义。此外,还有一个`Submit`对象用于渲染提交按钮,其第一个位置参数是按钮名称,第二个参数是按钮的值。
若项目需要特定的表单标记,可以覆盖和修改`django-crispy-forms`应用的模板。因为Python文件中没有硬编码的标记,所有生成的标记都是通过模板渲染的。只需将`django-crispy-forms`应用的模板复制到项目的模板目录,然后按需修改即可。
#### 2. 过滤对象列表
在Web开发中,除了表单视图,对象列表视图和详细视图也很常见。简单的列表视图按字母顺序或创建日期排列对象,但处理大量数据时不太友好。为了提高可访问性和便利性,应能按所有可能的类别过滤内容。
以下是实现过滤对象列表的步骤:
- **准备工作**:使用具有与流派、导演、演员关系的`Movie`模型进行过滤,同时可以按评级过滤。创建`movies`应用,并在设置的`INSTALLED_APPS`中添加该应用,然后在新应用中定义相关模型。
```python
# movies/models.py
# -*- coding: UTF-8 -*-
from django.db import models
from django.utils.translation import ugettext_lazy as _
RATING_CHOICES = (
(1, u"¶"),
(2, u"¶¶"),
(3, u"¶¶¶"),
(4, u"¶¶¶¶"),
(5, u"¶¶¶¶¶"),
)
class Genre(models.Model):
title = models.CharField(_("Title"), max_length=100)
def __unicode__(self):
return self.title
class Director(models.Model):
first_name = models.CharField(_("First name"), max_length=40)
last_name = models.CharField(_("Last name"), max_length=40)
def __unicode__(self):
return self.first_name + " " + self.last_name
class Actor(models.Model):
first_name = models.CharField(_("First name"), max_length=40)
last_name = models.CharField(_("Last name"), max_length=40)
def __unicode__(self):
return self.first_name + " " + self.last_name
class Movie(models.Model):
title = models.CharField(_("Title"), max_length=255)
genres = models.ManyToManyField(Genre, blank=True)
directors = models.ManyToManyField(Director, blank=True)
actors = models.ManyToManyField(Actor, blank=True)
rating = models.PositiveIntegerField(choices=RATING_CHOICES)
def __unicode__(self):
return self.title
```
- **创建过滤表单**:创建包含所有可能过滤类别的`MovieFilterForm`。
```python
# movies/forms.py
# -*- coding: UTF-8 -*-
from django import forms
from django.utils.translation import ugettext_lazy as _
from models import Genre
from models import Director
from models import Actor
from models import RATING_CHOICES
class MovieFilterForm(forms.Form):
genre = forms.ModelChoiceField(
label=_("Genre"),
required=False,
queryset=Genre.objects.all(),
)
director = forms.ModelChoiceField(
label=_("Director"),
required=False,
queryset=Director.objects.all(),
)
actor = forms.ModelChoiceField(
label=_("Actor"),
required=False,
queryset=Actor.objects.all(),
)
rating = forms.ChoiceField(
label=_("Rating"),
required=False,
choices=RATING_CHOICES,
)
```
- **创建视图**:创建`movie_list`视图,使用`MovieFilterForm`验证请求查询参数,并按所选类别进行过滤。
```python
# movies/views.py
# -*- coding: UTF-8 -*-
from django.shortcuts import render
from models import Genre
from models import Director
from models import Actor
from models import Movie, RATING_CHOICES
from forms import MovieFilterForm
def movie_list(request):
qs = Movie.objects.order_by('title')
form = MovieFilterForm(data=request.REQUEST)
facets = {
'selected': {},
'categories': {
'genres': Genre.objects.all(),
'directors': Director.objects.all(),
'actors': Actor.objects.all(),
'ratings': RATING_CHOICES,
},
}
if form.is_valid():
genre = form.cleaned_data['genre']
if genre:
facets['selected']['genre'] = genre
qs = qs.filter(genres=genre).distinct()
director = form.cleaned_data['director']
if director:
facets['selected']['director'] = director
qs = qs.filter(directors=director).distinct()
actor = form.cleaned_data['actor']
if actor:
facets['selected']['actor'] = actor
qs = qs.filter(actors=actor).distinct()
rating = form.cleaned_data['rating']
if rating:
facets['selected']['rating'] = \
(int(rating), dict(RATING_CHOICES)[int(rating)])
qs = qs.filter(rating=rating).distinct()
context = {
'form': form,
'facets': facets,
'object_list': qs,
}
return render(request, "movies/movie_list.html", context)
```
- **创建模板**:创建列表视图的模板,使用`facets`字典列出类别,并标记当前选中的类别。
```html
{# templates/movies/movie_list.html #}
{% extends "base_two_columns.html" %}
{% load i18n utility_tags %}
{% block sidebar %}
<div class="filters">
<h6>{% trans "Filter by Genre" %}</h6>
<div class="list-group">
<a class="list-group-item{% if not facets.selected.genre %}
active{% endif %}" href="{% append_to_query genre="" page="" %}">{%
trans "All" %}</a>
{% for cat in facets.categories.genres %}
<a class="list-group-item{% if facets.selected.genre
== cat %} active{% endif %}" href="{% append_to_query genre=cat.pk
page="" %}">{{ cat }}</a>
{% endfor %}
</div>
<h6>{% trans "Filter by Director" %}</h6>
<div class="list-group">
<a class="list-group-item{% if not facets.selected.director %}
active{% endif %}" href="{% append_to_query director="" page="" %}">{%
trans "All" %}</a>
{% for cat in facets.categories.directors %}
<a class="list-group-item{% if facets.selected.director
== cat %} active{% endif %}" href="{% append_to_query director=cat.pk
page="" %}">{{ cat }}</a>
{% endfor %}
</div>
<h6>{% trans "Filter by Actor" %}</h6>
<div class="list-group">
<a class="list-group-item{% if not facets.selected.actor %}
active{% endif %}" href="{% append_to_query actor="" page="" %}">{%
trans "All" %}</a>
{% for cat in facets.categories.actors %}
<a class="list-group-item{% if facets.selected.actor
== cat %} active{% endif %}" href="{% append_to_query actor=cat.pk
page="" %}">{{ cat }}</a>
{% endfor %}
</div>
<h6>{% trans "Filter by Rating" %}</h6>
<div class="list-group">
<a class="list-group-item{% if not facets.selected.rating %}
active{% endif %}" href="{% append_to_query rating="" page="" %}">{%
trans "All" %}</a>
{% fo
```
0
0
复制全文
相关推荐










