慕课网-Django入门到进阶-更适合Python小白的系统课程-第5章Django中的Form表单的使用-5-3模型表单

第5章 Django 中的 Form 表单的使用

5-3 模型表单

概念介绍

1.模型表单是 model 层的模型与 form 表单结合起来,通过表单层作为中介,渲染出前端表单,并通过表单直接读写数据库

2.模型表单基础模块继承于:forms.ModelForm

from django.forms import ModelForm
from myapp.models import Article

# Create the form class
class  ArticleForm(ModelForm):
    class Meta:
        model = Article
        fields = ['pub_date', 'headline', 'content', 'reporter']

# Creating a form to add an article.
form = ArticleForm()

# Creating a form to change an existing article
article = Article.objects.get(pk=1)
form = ArticleForm(instance=article)

Model 字段类型与 form 字段类型

模型字段 表单字段
AutoField 不呈现在表单中
BigAutoField 不呈现在表单中
BigIntegerField IntegerField 将 min_value 设置为 -9223372036854775808,将 max_value 设置为 9223372036854775807
BooleanField BooleanField
CharField CharField 将 max_length 设置为模型字段的 max_length,如果模型中设置了 null=True,会将 empty_value 设置为 None。
DateField DateField
DateTimeField DateTimeField
DecimalField DecimalField
EmailField EmailField
FileField FileField
FilePathField FilePathField
FloatField FloatField
ForeignKey ModelChoiceField
ImageField ImageField
IntegerField IntegerField
IPAddressField IPAddressField
GenericIPAddresField GenericIPAddresField
ManyToManyField ModelMultipleChoiceField
NullBooleanField NullBooleanField
SmallIntegerField IntegerField
TextField CharfField 设置中 widget=forms.Textarea
TimeField TimeField
URLField URLField

特殊说明

1.当 model 字段设置了blank=True,表单 required=False

2.表单 label 会设置 model 字段的 verbose_name

3.ForeignKey 由 django.forms.ModelChoiceField 表示,它是一个 ChoiceField,其选项是一个模型的 QuerySet

4.ManyToManyField 由 django.forms.ModelMultipleChoiceField 表示,它是一个 MultpleChoiceField,其选项为一个模型 QuerySet

实例

1.在命令行窗口进入 MySQL 界面,创建数据库 forms

create database forms default charset=utf8;

2.在项目 form 下目录 form,修改文件 settings.py,修改数据库配置

# 数据库配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'forms',
        'USER':'root',
        'PASSWORD':'123456',
        'HOST':'127.0.0.1',
        'PORT':'3306',
        'OPTIONS':{
            "init_command":"SET sql_mode='STRICT_TRANS_TABLES'"
        },
    }
}

3.在项目 form 下目录 app,修改文件 models.py

from django.db import models

class Auth(models.Model):
    username = models.CharField(max_length=18)
    password = models.CharField(max_length=18)

    def __str__(self):
        return 'username:{}'.format(self.username)

4.在项目 form 下,命令行窗口创建数据库表 app_auth 

python manage.py makemigrations
python manage.py migrate

5.在命令行窗口进入 MySQL 界面,查看数据表是否生成成功

use fomrs;
show tables;
show create table app_auth;

6.在项目 form 下目录 app,修改文件 forms.py,添加类 AuthModelForm

from django import forms
from django.forms import fields
from .models import Auth as AuthModel

class AuthModelForm(forms.ModelForm):
    class Meta:
        model = AuthModel
        fields = ['username', 'password']
        exclude = [] # 输入不转成表单字段的 model 字段
        field_classes = {   # 定义字段的类型,一般会按照 model 的类型自动转换
            'username': forms.CharField,
            'password': forms.CharField,
        }
        labels = {
            'username': '用户名',
            'password': '密码',
        }
        widgets = {
            'username': forms.TextInput(
                attrs={'placeholder':'请输入用户名'}
            ),
            'password': forms.PasswordInput(
                attrs={'placeholder':'请输入密码'}
            ),
        }
        error_messages = {
            'username': {'required': '用户名不可以为空'},
            'password': {'min_length': '最少不能低于10个字符'},
        }
    def clean_username(self):
        username = self.cleaned_data.get('username')
        if len(username) > 10:
            raise forms.ValidationError('用户名最大不能超过10')
        return username

class Auth(forms.Form):
    username = fields.CharField(
        max_length=18,
        min_length=3,
        required=True,
        label="用户名",
        widget=forms.TextInput(attrs={'placeholder':'最大不能超过18字符'}),
        error_messages={'max_length':'最大不能超过18字符!'}
    )
    password = fields.CharField(
        widget=forms.PasswordInput(attrs={'placeholder':'请输入密码'}),
        label="密码",
        required=True,
        min_length=10,
        error_messages={'min_length':'最小不能低于10个字符'}
    )

    def clean(self):
        password = self.cleaned_data.get('password', '')
        if not password:
            raise forms.ValidationError('密码不可以为空!')

    def clean_username(self):
        username = self.cleaned_data.get('username', '')
        if len(username) > 18:
            raise forms.ValidationError('用户名最大不能超过18')
        return username

7.在项目 form 下目录 app,修改文件 views.py,引用 AuthModelForm,把 Auth 改成 AuthModelForm

from django.shortcuts import render, redirect, reverse
from django.views.generic import View
from .forms import Auth, AuthModelForm

class Regist(View):
    TEMPLATE = 'regist.html'

    def get(self, request):
        form = AuthModelForm()
        return render(request, self.TEMPLATE, {'form': form})

    def post(self, request):
        # username = request.POST.get('username')
        # password = request.POST.get('password')
        form = AuthModelForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            print('username:', username)
            print('password', password)
        else:
            return render(request, self.TEMPLATE, {'form':form})
        return redirect(reverse('regist'))

8.在项目 form 下命令行窗口进入服务

python manage.py runserver 127.0.0.1:8000

9.测试

10.在项目 form 下目录 app,修改文件 views.py,保存数据,添加代码 form.save()

from django.shortcuts import render, redirect, reverse
from django.views.generic import View
from .forms import Auth, AuthModelForm

class Regist(View):
    TEMPLATE = 'regist.html'

    def get(self, request):
        form = AuthModelForm()
        return render(request, self.TEMPLATE, {'form': form})

    def post(self, request):
        # username = request.POST.get('username')
        # password = request.POST.get('password')
        form = AuthModelForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            form.save()
        else:
            return render(request, self.TEMPLATE, {'form':form})
        return redirect(reverse('regist'))

11.测试,添加数据

12.在命令行窗口进入 MySQL 界面,查看数据表是否生成成功

select * from app_auth;

13.在项目 form 下目录 app,修改文件 views.py,把数据传送给表单

from django.shortcuts import render, redirect, reverse
from django.views.generic import View
from .forms import Auth, AuthModelForm
from .models import Auth as AuthModel

class Regist(View):
    TEMPLATE = 'regist.html'

    def get(self, request):
        user = AuthModel.objects.filter(pk=1).first()
        if user:
            form = AuthModelForm(instance=user)
        else:
            form = AuthModelForm()
        return render(request, self.TEMPLATE, {'form': form})

    def post(self, request):
        # username = request.POST.get('username')
        # password = request.POST.get('password')
        form = AuthModelForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            form.save()
        else:
            return render(request, self.TEMPLATE, {'form':form})
        return redirect(reverse('regist'))

14.测试,表单中 "用户名" 已经收显示数据,但是 "密码" 没有显示数据

15.在项目 form 下目录 app,修改文件 forms.py,在代码类 AuthModelForm 中 widgets 的 password 添加 render_value 属性

from django import forms
from django.forms import fields
from .models import Auth as AuthModel

class AuthModelForm(forms.ModelForm):
    class Meta:
        model = AuthModel
        fields = ['username', 'password']
        exclude = [] # 输入不转成表单字段的 model 字段
        field_classes = {   # 定义字段的类型,一般会按照 model 的类型自动转换
            'username': forms.CharField,
            'password': forms.CharField,
        }
        labels = {
            'username': '用户名',
            'password': '密码',
        }
        widgets = {
            'username': forms.TextInput(
                attrs={'placeholder':'请输入用户名'},
            ),
            'password': forms.PasswordInput(
                attrs={'placeholder':'请输入密码'},
                render_value=True,
            ),
        }
        error_messages = {
            'username': {'required': '用户名不可以为空'},
            'password': {'min_length': '最少不能低于10个字符'},
        }
    def clean_username(self):
        username = self.cleaned_data.get('username')
        if len(username) > 10:
            raise forms.ValidationError('用户名最大不能超过10')
        return username

class Auth(forms.Form):
    username = fields.CharField(
        max_length=18,
        min_length=3,
        required=True,
        label="用户名",
        widget=forms.TextInput(attrs={'placeholder':'最大不能超过18字符'}),
        error_messages={'max_length':'最大不能超过18字符!'}
    )
    password = fields.CharField(
        widget=forms.PasswordInput(attrs={'placeholder':'请输入密码'}),
        label="密码",
        required=True,
        min_length=10,
        error_messages={'min_length':'最小不能低于10个字符'}
    )

    def clean(self):
        password = self.cleaned_data.get('password', '')
        if not password:
            raise forms.ValidationError('密码不可以为空!')

    def clean_username(self):
        username = self.cleaned_data.get('username', '')
        if len(username) > 18:
            raise forms.ValidationError('用户名最大不能超过18')
        return username

16.测试

17.如果出现错误查找对应问题,可在项目 form 下命令行窗口进入 shell 查看

python manage.py shell

18.查看

from django import froms
forms.PasswordInput
django.forms.widgets.PasswordInput
help(forms.PasswordInput)

 

posted on 2020-02-07 09:03  herisson_pan  阅读(11)  评论(0)    收藏  举报

导航