Django深入研究3(表单与模型、后台系统)

一、Django表单与模型

  表单是搜集用户数据信息的各种表单元素的集合,作用是实现网页上的数据交互,用户在网站输入数据信息,然后提交到网站服务器端进行处理(如数据录入和用户登录、注册等)。
  用户表单是Web开发的一项基本功能,Django的表单功能由Form类实现,主要分为两种:django.forms.Form和django.forms.ModelForm。前者是一个基础的表单功能,后者是在前者的基础上结合模型所生成的数据表单。

1、初识表单

  传统的表单生成方式是在模板文件中编写HTML代码实现,在HTML语言中,表单由标签实现。表单生成方式如下:

<!DOCTYPE html>
<html>
<body>

<form action="" method="post">
First name:<br>
<input type="text" name="firstname" value="Mickey">
<br>
Last name:<br>
<input type="text" name="lastname" value="Mouse">
<br><br>
<input type="submit" value="Submit">
</form>

</body>
</html>

  一个完整的表单主要有4个组成部分:提交地址、请求方式、元素控件和提交按钮。其说明如下:

  • 提交地址用于设置用户提交的表单数据应由哪个URL接收和处理,由控件的属性action决定。当用户向服务器提交数据时,若属性action为空,则提交的数据应由当前的URL来接收和处理,否则网页会跳转到属性action所指向的URL地址。
  • 请求方式用于设置表单的提交方式,通常是GET请求或POST请求,由控件 的属性method决定。
  • 元素控件是供用户输入数据信息的输入框。由HTML的控件实现,其控件属性type用于设置输入框的类型,常用的输入框类型有文本框、下拉框和复选框等。
  • 提交按钮供用户提交数据到服务器,该按钮也是由HTML的控件实现的。但该按钮具有一定的特殊性,因此不归纳到元素控件的范围内。

  上述的表单实现方式较为简单,但是实际使用时,表单数据会有很多,上述的方式就会有很大的代码量同时也不好维护,所以Django提供了更加完善的表单功能,演示之前,对之前的项目做出席位调整:在MyDjango的index中添加了空白文件form.py,该文件主要用于编写表单的实现功能,文件夹可自行命名;同时在文件夹templates中添加模板文件dataform.html,该文件用于将表单的数据显示到网页上。最后在文件form.py、views.py和data_form.html中分别添加以下代码:

#form.py代码,定义ProductForm表单对象
from django import forms 
from .models import *
class ProductForm(forms.Form):
    name = forms.CharField(max_length=20, label='名字')
    weight = forms.CharField(max_length=50, label='重量')
    size = forms.CharField(max_length=50, label='尺寸')
    #设置下拉框的值
    choices_list = [(i+1, v['type_name'])for i, v in enumerate(Product.objects.values('name'))]
    type = forms.ChoiceField(choices=choices_list, label='产品类型')
 
#views.py代码,将表单ProductForm实例化并将其传递到模板中生成网页内容   
from django.shortcuts import render
from .form import *
def index(request):
	product = ProductForm()

	return render(request, 'data_form.html', locals())
	
# data_form.html 代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% if product.errors %}
        <p>
            数据出错啦,错误信息:{{product.errors}}.
        </p>
    {%else%}
        <form action=""method="post">
        {% csrf_token%}
            <table>
                {{product.as_table}}
            </table>
            <input type="submit"value="提交">
        </form>
    {%endif%}
</body>
</html>

代码说明:
(1)在form.py中定义表单ProductForm,表单以类的形式表示。在表单中定义了不同类型的类属性,这些属性在表单中称为表单字段,每个表单字段代表HTML里的一个控件,这是表单的基本组成单位。
(2)在views.py中导入form.py所定义的ProductForm类,在视图函数index中对ProductForm实例化生成对象product,再将对象product 传递给模板data_form.html。
(3)模板 data_form.html将对象product以HTML的

的形式展现在网页上,
效果如下:
在这里插入图片描述

2、表单的定义

  从上面的例子发现,Django的表单功能主要是通过定义表单类,再由类的实例化生成HTML的表单元素控件,这样可以在模板中减少HTML的硬编码。每个HTML的表单元素控件由表单字段来决定,例如:从表单字段转换HTML元素控件可以发现:

  • 字段name的参数label将转换成HTML的标签
  • 字段name的forms.CharField类型转换成HTML的控件,标签是一个输入框控件,type="text”代表当前输入框为文本输入框,参数type用于设置输入框的类型。
  • 字段name的命名转换成控件的参数name,表单字段的参数max_length将转换成控件的参数required maxlength。

  除了上述,Django还提供多种扁担字段,如下:
在这里插入图片描述在这里插入图片描述
  表单字段除了转换HTML控件之外,还具有一定的数据格式现范,数据格式规范主要由字段类型和字段参数共同实现。每个不同类型的表单字段都有一些自己特殊的参数,但每个表单字段都具有如下的共同参数。
在这里插入图片描述

3、表单与模型

  我们知道Django的表单分为两种:django.forms.Form和django.forms.ModelForm。前者是一个基础的表单功能,后者是在前者的基础上结合模型所生成的数据表单。数据表单是将模型的字段转换成表单的字段,再从表单的字段生成HTML的元素控件,这是日常开发中常用的表单之一。
  演示如下,首先在form.py定义ProductModelForm,该表单继承自父类forms.ModelForm。这里的例子用于理解模型和表单的交互,并不是同一个模型哈。[惊愕]

# 表单和模型
from django import forms
from .models import *
from django.core.exceptions import ValidationError
#数据库表单
class ProductModelForm(forms.ModelForm):
    #添加模型外的表单字段
    productId = forms.CharField(max_length=20, label='产品序号')
    #模型与表单设置
    class Meta:
        #绑定模型
        model = Performer
        #fields属性用于设置转换字段,'all'是将全部模型字段转换成表单字段
        #fields='all
        fields=['id','name','nationality','masterpiece']
        #exclude用于禁止模型字段转换表单字段
        exclude=[]
        #1abe1s设置HTML元素控件的1abe1标签
        labels={
            'id':'产品编号',
            'name':'姓名',
            'nationality':'国籍',
            'masterpiece':'尺寸',

        }
        #定义widgets,设置表单字段的CSS样式
        widgets={
        'name':forms.widgets.TextInput(attrs={'class':'cl'}),
        }
        #定义字段的类型,一般情况下模型的字段会自动转换成表单字段
        field_classes={
        'name':forms.CharField
        }
#帮助提示信息
        help_texts={
        'name':''
        }
        #自定义错误信息
        error_messages={
        #al1设置全部错误信息
        '__all__':{'required':'请输入内容',
                   'invalid':'请检查输入内容'
                   },
        #设置某个字段的错误信息
        'nationality':{'required':'请输入重量数值',
                  'invalid':'请检查数值是否正确'}
        }
    #自定义表单字段weight的数据清洗
    def clean_weight(self):
        #获取字段weight的值
        data=self.cleaned_data['nationality']
        return data+'g'

  上述代码中,表单类ProductModelForm可分为三大部分:添加模型外的表单字段、模型与表单设置和自定义表单字段weight的数据清洗函数,说明如下:

  • 添加模型外的表单字段是在模型已有的字段下添加额外的表单字段。
  • 模型与表单设置是将模型的字段转换成表单字段,由类Meta的属性实现两者的字段转换。
  • 自定义表单字段weight的数据清洗函数只适用于字段weight的数据清洗。

综上所述,模型字段转换成表单字段主要在类Meta中实现。在类Meta中,其属性说明如下:
在这里插入图片描述
  值得注意的是,一些较为特殊的模型字段在转换表单时会有不同的处理方式。例如模型字段的类型为AutoField,该字段在表单中不存在对应的表单字段;模型字段类型为ForeignKey和Many ToManyField,在表单中对应的表单字段为ModelChoiceField和ModelMultipleChoiceField。
  自定义表单字段weight的数据清洗函数是在视图函数中使用cleaned_data方法时,首先判断当前清洗的表单字段是否已定义数据清洗函数。例如上述的clean_weight函数,在清洗表单字段weight的数据时会自动执行该自定义函数。在自定义数据清洗函数时,必须以“clean字段名”的格式作为函数名,而且函数必须有return返回值。如果在函数中设置ValidationError了异常抛出,那么该函数可视为带有数据验证的清洗函数。

二、后台系统

  Admin后台系统也称为网站后台管理系统,主要用于对网站前台的信息进行管理,如文字、图片、影音和其他日常使用文件的发布、更新、删除等操作,也包括功能信息的统计和管理,如用户信息、订单信息和访客信息等。简单来说,就是对网站数据库和文件的快速操作和管理系统,以使网页内容能够及时得到更新和调整。

1、走进Admin

  当一个网站上线之后,网站管理员是通过网站后台系统对网站进行管理和维护的。Django已内置了强大的Admin后台系统,在创建Django项目的时候,可以从配置文件settings.py中看到项目已默认启用Admin后台系统。在INSTALLEDAPPS中已配置了Django的Admin后台系统,如果网站不需要Admin后台系统,可以将配置信息删除,这样可以减少程序对系统资源的占用。此外,在根目录的urls.py中也可以看到Admin的URL地址信息,我们在浏览器上输入http://127.0.0.1:8000/admin 就能访问Admin后台系统,如下所示。
在这里插入图片描述
  在访问Admin后台系统时,首先需要输入用户的账号和密码登录才能进入后台管理界面。创建用户的账号和密码之前,必须确保项目的模型在数据库中有相应的数据表。
  如果Admin后台系统以英文的形式显示,那么我们还需要在项目的settings.py中设置MIDDLEWARE中间件,将后台内容以中文形式显示。添加的中间件是有先后顺序的,具体设置如下。
在这里插入图片描述
  完成上述设置后,下一步是创建用户的账号和密码,创建方法由Django的管理工具manage.py完成,在PyCharm的Terminal模式下输入创建指令,代码如下:

python manage.py createsuperuser

  然后一步步设置账号名和邮箱以及地址,在创建用户信息时,用户名和邮箱地址可以为空,如果用户名为空会默认使用计算机的用户名,而设置用户密码时,输入的密码不会显示在计算机的屏幕上。完成用户创建后,打开数据表auth_user可看到新增了一条用户信息,如下所示。
在这里插入图片描述
  然后再登录界面登录就可进入后台管理系统,界面如下:
在这里插入图片描述
  在Admin后台系统中可以看到,主要功能分为站点管理、认证和授权、用户和组,说明如下:

  • 站点管理是整个网站的App管理界面,主要管理Django的App下所定义的模型。
  • 认证和授权是Django内置的认证系统,也是项目的一个App。
  • 用户和组是认证和授权所定义的模型,分别对应数据表auth_user 和auth_
    user groups。
      若我们想把已经建立的app index的模型添加在管理系统,只需要在index的admin.py中添加如下代码:
from django.contrib import admin
from .models import *
# Register your models here.
#方法一
#将模型直接注册到admin后台
admin.site.register(Performer)

#方法二:
#自定义ProductAdmin 类并继承 ModelAdmin
#注册方法一,使用Python 装饰器将ProductAdmin 和模型Product绑定并注册到后台
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):

    #设置显示的字段
    list_display = ['id','name', 'type']
#注册方法二
#admin.site.register(Product,ProductAdmin)

  上述代码以两种方法将数据表注册到Admin后台系统,方法一是基本的注册方式;方法二是通过类的继承方式实现注册。日常的开发都是采用第二种方法实现的,实现过程如下:

  • 自定义ProductAdmin类,使其继承ModelAdmin。ModelAdmin主要设置模型信息如何展现在Admin后台系统中。
  • 将ProductAdmin类注册到Admin后台系统中有两种方法,两者都是将模型Product和ProductAdmin类绑定并注册到Admin后台系统。
    效果展示:
    在这里插入图片描述

2、Admin的基本配置

  前面,我们将数据表成功展现在站点管理的页面,但对一个不会网站开发的使用者来说,可能无法理解INDEX和Products的含义,而且用英文表示也会影响整个网页的美观。因此,我们需要将INDEX和Products转换成具体的中文内容。将INDEX和Products设置中文显示需要分别使用不同的方法实现,因为INDEX和Products在项目中分别代表不同的意思,前者是一个App的命名,后者是一个App中定义的模型。
  首先实现INDEX的中文显示,主要由App的__init.py文件实现,实现代码如下:

#INDEX设置中文,代码编写在App(index)的_init.py文件中
from django.apps import AppConfig
import os
#修改App在Admin后台显示的名称
#default_app_config的值来自apps.py的类名
default_app_config='index.IndexConfig'
#获取当前App的命名
def get_current_app_name(_file):
    return os.path.split(os.path.dirname(_file))[-1]
#重写类IndexConfig
class IndexConfig(AppConfig):
    name=get_current_app_name(__file__)
    verbose_name='网站首页'

  当项目启动时,程序会从初始化文件__init获取重写的IndexConfig类,类属性verbosename用于设置INDEX的中文内容。
  然后将模型设置中文显示,在models.py中设置类Meta的类属性verbose_name_plural即可实现。值得注意的是,Meta的类属性还有verbose_name,两者都能设置Products的中文内容,但verbose_name是以复数形式表示的,如将Products设置为“演员信息”,verbose_name会显示为“演员信息s”,实现代码如下:

class Performer(models.Model):

    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=20)
    nationality = models.CharField(max_length=20)
    masterpiece = models. CharField(max_length=50)

    class Meta:

        # 如只设置 verbose_name,在Admin会显示为”产品信息s"
        # verbose_name ='演员信息'
        verbose_name_plural = '演员信息'

  除此之外,我们还可以进一步完善Admin网页标题信息,在App的admin.py文件中编写以下代码:

#修改title和header
admin.site.site_title = 'MyDjango后台管理'
admin.site.site_header = 'MyDjango'

效果如下:
在这里插入图片描述
  当一个数据表中存储了成千上万的数据,在Admin中查找该表的某条数据信息时,如果不使用一些查找功能,是无法精准地找到需要的数据信息的。为解决这个问题,可以在admin.py中进一步优化ProductAdmin,优化代码如下:

@admin.register(Performer)
class ProductAdmin(admin.ModelAdmin):

    #设置显示的字段
    list_display = ['id','name', 'nationality','masterpiece']
#注册方法二
#admin.site.register(Product,ProductAdmin)
    # 设置可搜索的子段开在Admin后台数据生成搜系框,如有外键,应使用双下画线连接两个模型的字段
    search_fields = ['id','name', 'nationality','masterpiece']
    # 设置过滤器,在后台数据的右侧生成导航栏,如有外键,应使用双下画线连接两个模型的字段
    list_filter=['name', 'nationality','masterpiece']
    # 设置排序方式,['id']为升序,降序为[’-id']
    ordering = ['id']
    # 设置时间选择器,如字段中有时间格式才可以使用
    # date hierarchy=Field
    # 在添加新数据时,设置可添加数据的字段
    fields = ['name', 'nationality','masterpiece']
    # 设置可读字段,在修改或新增数据时使其无法设置
    readonly_fields=['name']

在这里插入图片描述
  值得注意的是,如果readonly_fields和fields属性设置了模型的同一个字段,那么在新增数据的时候,该模型字段是无法输入数据的。例如上述设置的字段name,在新增数据时,该字段的值默认为空并且无法输入数据,效果如图。
在这里插入图片描述

  前面的章节讲述了Admin的基本设置,但实际上每个网站的功能和需求都是各不相同的,这也导致了Admin 后台功能有所差异。因此,通过重写ModelAdmin的方法可以实现Admin的二次开发,满足多方面的开发需求,这部分内容将在后面文章讲解。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值