VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • Form和ModelForm组件(2)

body> <div class="container"> <div class="row"> <form action="/login2/" method="post" novalidate class="form-horizontal"> {% csrf_token %} <div class="form-group"> <label for="{{ form_obj.username.id_for_label }}" class="col-md-2 control-label">{{ form_obj.username.label }}</label> <div class="col-md-10"> {{ form_obj.username }} <span class="help-block">{{ form_obj.username.errors.0 }}</span> </div> </div> <div class="form-group"> <label for="{{ form_obj.pwd.id_for_label }}" class="col-md-2 control-label">{{ form_obj.pwd.label }}</label> <div class="col-md-10"> {{ form_obj.pwd }} <span class="help-block">{{ form_obj.pwd.errors.0 }}</span> </div> </div> <div class="form-group"> <label class="col-md-2 control-label">{{ form_obj.gender.label }}</label> <div class="col-md-10"> <div class="radio"> {% for radio in form_obj.gender %} <label for="{{ radio.id_for_label }}"> {{ radio.tag }}{{ radio.choice_label }} </label> {% endfor %} </div> </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <button type="submit" class="btn btn-default">注册</button> </div> </div> </form> </div> </div> <script src="/static/jquery-3.2.1.min.js"></script> <script src="/static/bootstrap/js/bootstrap.min.js"></script> </body> </html>

批量添加样式

    可通过重写form类的init方法来实现。

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三",
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "用户名最短8位"
        }
    ...

    def __init__(self, *args, **kwargs):
        super(LoginForm, self).__init__(*args, **kwargs)
        for field in iter(self.fields):
            self.fields[field].widget.attrs.update({
                'class': 'form-control'
            })

简单写一个小项目:book表的添加和数据展示

views.py内容如下:

from django.shortcuts import render,HttpResponse,redirect
from app01 import models
from django import forms
# Create your views here.

class BookForm(forms.Form):
    title = forms.CharField(
        max_length=16,
        label='书名:',
        initial='zhang',
        # widget = forms.widgets.PasswordInput(attrs={'class': 'form-control'},render_value=True),
        widget = forms.widgets.TextInput(attrs={'class': 'form-control'},),

    )
    # title2 = forms.CharField(
    #     max_length=16,
    #     label='书名:',
    #     initial='zhang',
    #     # widget = forms.widgets.PasswordInput(attrs={'class': 'form-control'},render_value=True),
    #     widget=forms.widgets.TextInput(attrs={'class': 'form-control'}, ),
    #
    # )
    sex = forms.ChoiceField(
        choices=(
            ('1','男'),
            ('2','女'),
        )
        ,
        label='性别:',
        # widget=forms.widgets.RadioSelect(),
        # widget=forms.widgets.RadioSelect(),
        # widget=forms.widgets.SelectMultiple(attrs={'class':'form-control'}),
        widget=forms.widgets.Select(attrs={'class':'form-control'}),
        # widget=forms.widgets.CheckboxInput(),
        # widget=forms.widgets.CheckboxSelectMultiple(),
    )
    publishDate = forms.DateField(
        label='出版日期:',
        widget=forms.widgets.TextInput(attrs={'type':'date','class':'form-control'}),
    )
    price=forms.DecimalField(
        max_digits=5,
        decimal_places=2,
        label='书籍的价格:',
        widget=forms.widgets.NumberInput(attrs={'class': 'form-control'}
    ))

    # publish = forms.ModelChoiceField(
    #     label='出版社:',
    #     queryset=models.Publish.objects.all(),
    #     widget=forms.widgets.Select(attrs={'class': 'form-control'}
    # ))
    publish_id = forms.ChoiceField(
        label='出版社:',
        widget=forms.widgets.Select(attrs={'class': 'form-control'}
    ))
    authors = forms.ModelMultipleChoiceField(

        queryset=models.Author.objects.all(),
        widget = forms.widgets.SelectMultiple(attrs={'class': 'form-control'}
    ))

    def __init__(self,*args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['publish_id'].choices = models.Publish.objects.values_list('pk','name')


def index(request):
    if request.method == 'GET':
        form_obj = BookForm()

        return render(request,'index.html',{'form_obj':form_obj})

    else:
        print(request.POST)
        form_obj = BookForm(request.POST)
        print(form_obj.is_valid())
        print(form_obj.errors)
        if form_obj.is_valid():
            print(form_obj.cleaned_data)
            authors_obj = form_obj.cleaned_data.pop('authors')
            new_book_obj = models.Book.objects.create(**form_obj.cleaned_data)
            new_book_obj.authors.add(*authors_obj)
            return redirect('show')

        else:
            print(form_obj.errors)
            return render(request,'index.html',{'form_obj':form_obj})


def show(request):

    book_objs = models.Book.objects.all()

    return render(request,'show.html',{'book_objs':book_objs})

def edit_book(request,n):


    return HttpResponse('欢迎来到编辑页面')


def delete_book(request,n):
    return HttpResponse('欢迎来到删除页面')

  urls.py内容如下

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index,name='index'),
    url(r'^show/', views.show,name='show'),
    url(r'^edit_book/(\d+)/', views.edit_book,name='edit_book'),
    url(r'^delete_book/(\d+)/', views.delete_book,name='delete_book'),
]

  index.html内容如下:

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.0-dist/dist/css/bootstrap.min.css' %}">
</head>
<body>

<h1>展示页面</h1>
{#<div>#}
{#    {{ form_obj.as_p }}#}
{##}
{#</div>#}

{#{% for field in form_obj %}#}
{#    <div>#}
{#        {{ field }}#}
{#    </div>#}
{##}
{#{% endfor %}#}

<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form action="" novalidate method="post">
                {% for field in form_obj %}
                    <div class="form-group {% if field.errors.0 %}has-error{% endif %}">
                        <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                        {{ field }}
                        <span class="text-danger">{{ field.errors.0 }}</span>
                    </div>
                {% endfor %}


                {#                <div class="form-group">#}
                {#                    <label for="{{ form_obj.sex.id_for_label }}">{{ form_obj.sex.label }}</label>#}
                {#                    {{ form_obj.sex }}#}
                {#                    {{ form_obj.sex.errors.0 }}#}
                {#                </div>#}
                {#            <div class="form-group">#}
                {#                    <label for="{{ form_obj.publishDate.id_for_label }}">{{ form_obj.publishDate.label }}</label>#}
                {#                    {{ form_obj.publishDate }}#}
                {#                    {{ form_obj.publishDate.errors.0 }}#}
                {#                </div>#}
                {#                <div class="form-group">#}
                {#                    <label for="{{ form_obj.price.id_for_label }}">{{ form_obj.price.label }}</label>#}
                {#                    {{ form_obj.price }}#}
                {#                    <span class="text-danger">{{ form_obj.price.errors.0 }}</span>#}
                {#                </div>#}
                {#            <div class="form-group">#}
                {#                    <label for="{{ form_obj.publish.id_for_label }}">{{ form_obj.publish.label }}</label>#}
                {#                    {{ form_obj.publish }}#}
                {#                    <span class="text-danger">{{ form_obj.publish.errors.0 }}</span>#}
                {#                </div>#}
                {#            <div class="form-group">#}
                {#                    <label for="{{ form_obj.authors.id_for_label }}">{{ form_obj.authors.label }}</label>#}
                {#                    {{ form_obj.authors }}#}
                {#                    <span class="text-danger">{{ form_obj.authors.errors.0 }}</span>#}
                {#                </div>#}
                <input type="submit">
            </form>
        </div>
    </div>
</div>


<div>


</div>


</body>
<script src="{% static 'bootstrap-3.3.0-dist/dist/jQuery/jquery-3.1.1.js' %}"></script>
<script src="{% static 'bootstrap-3.3.0-dist/dist/js/bootstrap.min.js' %}"></script>
</html>

  show.html内容如下

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.0-dist/dist/css/bootstrap.min.css' %}">
</head>
<body>

<h1>数据展示</h1>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <table class="table">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>title</th>
                        <th>性别</th>
                        <th>出版日期</th>
                        <th>出版社</th>
                        <th>作者</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    {% for book_obj in book_objs %}
                         <tr>
                            <td>{{ book_obj.pk }}</td>
                            <td>{{ book_obj.title }}</td>
                            <td>{{ book_obj.get_sex_display }}</td>
                            <td>{{ book_obj.publishDate|date:'Y-d-m' }}</td>
                            <td>{{ book_obj.publish.name }}</td>
                            <td>
                                {% for author in book_obj.authors.all %}
                                    {{ author.name }}
                                {% endfor %}

                            </td>
                            <td>
                                <a class="btn btn-warning" href="{% url 'edit_book' book_obj.pk  %}">编辑</a>
                                <a class="btn btn-danger" href="{% url 'delete_book' book_obj.pk  %}">删除</a>
                            </td>
                         </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>

</div>

</body>
<script src="{% static 'bootstrap-3.3.0-dist/dist/jQuery/jquery-3.1.1.js' %}"></script>
<script src="{% static 'bootstrap-3.3.0-dist/dist/js/bootstrap.min.js' %}"></script>
</html>

  别忘了在settings.py中配置静态文件

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'statics'),
]

  别忘了去下载一个bootstrap和jquery然后在上面的html文件中引入一下。

  models.py文件内容如下:

from django.db import models

# Create your models here.


from django.db import models

# Create your models here.


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    age=models.IntegerField()
    authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid")
    def __str__(self):
        return self.name
class AuthorDetail(models.Model):

    nid = models.AutoField(primary_key=True)
    birthday=models.DateField()
    telephone=models.BigIntegerField()
    addr=models.CharField( max_length=64)

class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    city=models.CharField( max_length=32)
    email=models.EmailField()
    def __str__(self):
        return self.name

class Book(models.Model):

    nid = models.AutoField(primary_key=True)
    title = models.CharField( max_length=32)
    sex_choice = (
        (1,'男'),
        (2,'女'),
    )
    sex = models.IntegerField(choices=sex_choice,default=1)
    publishDate=models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2)
    publish=models.ForeignKey(to="Publish",to_field="nid")
    authors=models.ManyToManyField(to='Author',)
    def __str__(self):
        return self.title

  别忘了给每个表添加一些数据。

七 ModelForm

  通常在Django项目中,我们编写的大部分都是与Django 的模型紧密映射的表单。 举个例子,你也许会有个Book 模型,并且你还想创建一个form表单用来添加和编辑书籍信息到这个模型中。 在这种情况下,在form表单中定义字段将是冗余的,因为我们已经在模型中定义了那些字段。

  基于这个原因,Django 提供一个辅助类来让我们可以从Django 的模型创建Form,这就是ModelForm。

modelForm定义

    form与model的终极结合,会根据你model中的字段转换成对应的form字段,并且并你生成标签等操作。

    比如你的models中的表是下面的内容:

class Book(models.Model):

    nid = models.AutoField(primary_key=True)
    title = models.CharField( max_length=32)
    publishDate=models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2)
    publish=models.ForeignKey(to="Publish",to_field="nid")
    authors=models.ManyToManyField(to='Author',)
    def __str__(self):
        return self.title

  

    modelform类的写法。

class BookForm(forms.ModelForm):

    class Meta:
        model = models.Book
        fields = "__all__"
        labels = {
            "title": "书名",
            "price": "价格"
        }
        widgets = {
            "password": forms.widgets.PasswordInput(attrs={"class": "c1"}),
            "publishDate": forms.widgets.DateInput(attrs={"type": "date"}),
        }

class Meta下常用参数:

model = models.Book  # 对应的Model中的类
fields = "__all__"  # 字段,如果是__all__,就是表示列出所有的字段
exclude = None  # 排除的字段
labels = None  # 提示信息
help_texts = None  # 帮助提示信息
widgets = None  # 自定义插件
error_messages = None  # 自定义错误信息
error_messages = {    'title':{'required':'不能为空',...} #每个字段的所有的错误都可以写,...是省略的意思,复制黏贴我代码的时候别忘了删了...}
 

  

  批量添加样式:和form的一样

class BookForm(forms.ModelForm):    #password = forms.CharField(min_length=10) #可以重写字段,会覆盖modelform中的这个字段,那么modelform下面关于这个字段的设置就会被覆盖,比如果设置插件啊,error_messages啊等等,
    r_password = forms.CharField() #想多验证一些字段可以单独拿出来写,按照form的写法,写在Meta的上面或者下面都可以
    class Meta:
        model = models.Book
        # fields = ['title','price']
        fields = "__all__" #['title,'price'] 指定字段生成form
        # exclude=['title',] #排除字段
        labels = {
            "title": "书名",
            "price"