第二章:数据模型建立

教学目的

  • 了解模板引擎的创建
  • 理解模板引擎的基本语法
  • 了解系统设计的基本原则,重点理解数据库的设计。
  • 了解ORM概念,理解数据模型创建方法。

模板引擎设置

Django的核心组件包括:

  • 模型(Model) :定义数据结构,通常与数据库交互。
  • 模板(Template) :定义用户界面的外观,使用Django模板语言。
  • 视图(View) :处理业务逻辑,从模型中获取数据,并将其传递给模板。

修改第一个视图样式

def index(request):
    return HttpResponse("<h1 style='color:red'>我的第一个Django视图</h1>")

真正的项⽬⾥⾯我们不会这样去渲染HTML。视图仅仅是提供数据, 然后渲染部分是Django模板引擎的职责。

模板引擎:是混⼊了原始HTML和⼀些特殊标签 {% for … in… %} 和 {{ variable }} 的html命名的文件,用于高质量的渲染HTML页面结构。

注意:模板和静态文件可以存放在各个应用程序下面,但是我们建议通过一个公共文件夹来存放所有应用下面的模板文件。

模板引擎的基本设置

配置模板引擎文件存放位置
  1. 在项目根目录中创建 templates 文件夹,用于存放模板文件。

  2. 在项目根目录中创建 static文件夹,用于存放静态文件,页面中用到的 js、图片、css文件

  3. settings.py配置模版文件路径

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')], #①
            'APP_DIRS': False,#②
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    • ①:定义了模板文件的位置,井且该目录的名称为templates, BASE_DIR
      表示本项目的根目录 , 用 os.path.join() 函数将两者连接起来,即模板目录的位置是相对根目录的 templates 目录
    • i吾句②:将 APP_DIRS 设置为 False , 即不再允许 Django 按照默认方式在应用目录中寻找模板文件
配置静态文件存放位置

样式表、JS脚本、图片等都是静态文件。

settings.py配置静态文件路径:

STATIC_URL = '/static/'
STATICFILES_DIRS = [(os.path.join(BASE_DIR, 'static'))]
  • 第一行:指定访问静态文件的URL地址
  • 第二行:指定了静态文件存放目录的位置
应用程序的其他配置

settings.py配置文件中修改

LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_TZ = False # 否则日期显示不一致
  • LANGUAGE_CODE :设置项目的语言,如果用汉语,则设置为 'zh-hans'
  • TIME_ZONE : 设置时区,通常使用东八区
  • USE_TZ :是否进行时区转换,设为False,不进行转换,否则可能出现8个小时的时间错误。
  • USE_I18N :国际化,指的是设计应用程序,使其能够适应不同的语言和地区,而不需要进行工程上的更改,国际化影响日期、语言等格式问题

页面渲染

render()函数

render(request, template_name, context=None, content_type=None, status=None, using=None)

将给定的模板与给定的上下文字典组合在一起,并以渲染的文本返回一个 HttpResponse 对象。

  • 必选参数

    • request

      用于生成此响应的请求对象。

    • template_name

      要使用的模板的全名(包含路径)。

  • 可选参数

    • context
      要添加到模板上下文的值的字典。 默认情况下,这是一个空的字典。 如果字典中的值是可调用的,则视图将在渲染模板之前调用它。重要:用于向页面传递值
    • content_type
      用于结果文档的MIME 类型。默认 ‘text/html’ ,取默认值。
    • status
      响应的状态代码默认为“200”,取默认值。
    • using
      用于加载模板的模板引擎的 :setting:NAME ,取默认值。

复习:Python三大重要数据类型

快速学习教程:https://www.runoob.com/python/python-while-loop.html

列表

列表类似其他语言中的数组,用来存放一系列数据,具有以下特点:

  • 列表可以嵌套
  • 可以是不同的数据类型
  • 列表大小不限
  1. 列表的创建

    list1 =list()  #创建空列表
    list2 =['程序员','网络工程师','数据库管理员','产品经理','项目经理','实施经理']
    
  2. 列表元素的修改

    1. 末尾添加元素 list2.append('数据挖掘')
    2. 中间添加元素 list2.insert(2,'数据工程师') 下标从0开始
    3. 删除指定元素 list2.remove('数据工程师')
    4. 清空列表 list2.clear()
  3. 修改列表的值 list2[2] = '数据管理员' 修改第三个元素为数据管理员,下标从0开始

  4. 截取列表语法: list[start:end] 从start到end-1,下标从0开始,可以是负数

  5. 列表生成式

    list1 =range(1,10)
    list2 =[item*2 for item in list1]
    print('==列表1:',list(list1))
    print('==列表2:',list2)
    

    range(start, stop[, step])函数:生成一个序列数据

    • start: 计数从 start 开始。默认是从 0 开始。例如 range(5) 等价于 range(0, 5)
    • stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是 [0, 1, 2, 3, 4] 没有 5
    • step:步长,默认为 1。例如:range(0, 5) 等价于 range(0, 5, 1)

    list( seq )函数:把一个类似类表的对象转为列表

元组
  • 元组与列表类似,写在小括号中的元素序列,列表是写在中括号中的元素序列
  • 列表可以增删改,元组创建后不能修改
  • 元组访问截取方式和列表相同
字典
  • 字典是另一种可变容器模型,且可存储任意类型对象。
  • 字典的每个键值 key=>value 对用冒号 : 分割,每个对之间用逗号(,)分割,整个字典包括在花括号 {}
  1. 字典的创建

    dict1 =dict() # 创建空字典
    dict2= {'name':'张三','age':18}
    dict3 = dict(name='李四',age=18,gender='女')
    print("===字典2:",dict2)
    print("===字典3:",dict3)
    
  2. 字典的访问

    print(dict2['name'])
    print(dict2.get('gender','男'))
    
  3. 字典的修改与添加

    dict2['gender']='男'  # 添加元素
    dict3['gender']='男' #修改元素
    
  4. 字典几个常用函数

    • dict.clear() 删除字典内所有元素
    • dict.items() 返回字典的键-值元组列表,常用于字典的遍历
    • dict.keys() 返回字典中的所有键,需要通过list()函数转成列表
    • dict.values() 返回字典中的所有值,需要通过list()函数转成列表
    • pop(key[,default]) 删除字典 key(键)所对应的值,返回被删除的值。
    • dict.update(dict2) 把字典dict2的键/值对更新到dict里,用于两个字典合并

模板语法

  1. 输出变量:{{变量名}}使用双括号来输出变量

    <div>我所在公司:{{name}}</div>
    
  2. 输出列表

    #view
    def tpl(request):
        name ="升阳"
        roles = ['程序员','网络工程师','数据库管理员','产品经理','项目经理','实施经理']
        return render(request,'tpl.html',{'name':name,"roles":roles})
    
    #html
    <h2>核心职位</h2>
      <div>{{roles.0}}</div>
      <div>{{roles.1}}</div>
    

    5行和6行通过列表的下标进行元素的访问

     <h2>全部职位</h2>
      <ul>
        {% for item in roles %}
          <li>{{item}}</li>
        {% endfor %}
      </ul>
    

    循环访问列表中的所有元素

  3. 输出字典

    user_info = {"name":"升阳","age":20,"sex":"男"}
    
    <h2>人员信息</h2>
      <h5>人员信息列</h5>
      <ul>
        {% for item in user_info.keys %}
          <li>{{item}}</li>
        {% endfor %}
      </ul>
    

    输出字典中的键

    <h5>人员信息值</h5>
      <ul>
        {% for item in user_info.values %}
          <li>{{item}}</li>
        {% endfor %}
      </ul>
    

    输出字典中的值

    <h5>人员信息键值对</h5>
      <ul>
        {% for k,v in user_info.items %}
          <li>{{k}} = {{v}}</li>
        {% endfor %}
      </ul>
    

    输出字典中的键值对

  4. 列表字典嵌套输出,常用的一种数据结构

    user_list = [
            {"name":"张三","age":22,"gender":"男"},
            {"name":"柴桑","age":30,"gender":"男"},
            {"name":"浔阳","age":24,"gender":"男"},
            {"name":"李四","age":42,"gender":"女"},
            {"name":"王五","age":32,"gender":"男"},
            {"name":"赵六","age":22,"gender":"女"},
        ]
    
    <hr>
      <h2>员工信息</h2>
      <h5>首席工程师</h5>
      <div>{{user_list.0.name}}</div>
    

    输出第一个行的元素

    <h5>所有工程师</h5>
      <ul>
        {% for item in user_list %}
          <li>姓名:{{item.name}},年龄:{{item.age}}</li>
        {% endfor %}
      </ul>
    

    输出所有元素

  5. 判断语句

    <h5>所有女工程师</h5>
      <ul>
        {% for item in user_list %}
          {% if item.gender == '女' %}
          <li>姓名:{{item.name}},年龄:{{item.age}},性别:{{item.gender}}</li>
          {% endif %}
        {% endfor %}
      </ul>
    

    单分支结构

    <h5>三十岁以上或者女工程师</h5>
      <ul>
        {% for item in user_list %}
          {% if item.gender == '女' %}
          <li>姓名:{{item.name}},年龄:{{item.age}},性别:{{item.gender}}</li>
          {% elif item.age > 30 %}
          <li>姓名:{{item.name}},年龄:{{item.age}},性别:{{item.gender}}</li>
          {% endif %}
        {% endfor %}
      </ul>
    

    多条件

    <h5>红色显示所有女工程师</h5>
      <ul>
      {% for item in user_list %}
          {% if item.gender == '女' %}
          <li style="color: red;">姓名:{{item.name}},年龄:{{item.age}},性别:{{item.gender}}</li>
          {% else %}
          <li>姓名:{{item.name}},年龄:{{item.age}},性别:{{item.gender}}</li>
          {% endif %}
      {% endfor %}
      </ul>
    

数据模型建立

ORM简介

动态网站就是当用户发起访问请求时 ,网站实时地从数据库提取内容并呈现在网页上,在这类动态网站中,大多数是通过数据库实现对数据的保存和读取的,所以数据库是网站最基本和底层的组成部分。

Python 本身有读取数据库的模块可以通过 SQL 语句直接实现程序和数据库的交互 。 Django 用另外一种方式解决了这个问题 ,在这种方式中不需要开发者使用 SQL 语句,而是使用更 Python 化的方式实现对数据库的操作,这就是 ORM,对象关系映射

ORM 的作用是在关系型数据库和业务实体对象之间进行映射,这样在操作业务对象时,就不需要再去和复杂的 SQL 语句打交道,只需简单地操作对象的属性和方法。

Django 的 ORM 表现方式就是编写数据模型类,这些类可 以 写到任何文件中,通常写在每个应用的 models.py 文件中 , 每个数据模型类都是 django .db.models.Model 的子类。

当数据模型类写好之后,通过执行 Django 的数据迁移操作就能够创建相应的数据库表,以后如果要修改数据库表的结构,只需要修改数据模型类,迁移数据就能够实现数据库结构的调整。

数据模型设计(数据表设计)

在这里插入图片描述

创建并设置数据库

  1. 创新数据库
    在这里插入图片描述

  2. settings.py配置mysql数据库链接。

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.mysql",
            "NAME": "employ",
            "USER": "root",
            "PASSWORD": "sunrise123",
            "HOST": "127.0.0.1",
            "PORT": "3306",
        }
    }
    
    • 把数据库引擎ENGINE修改为django.db.backends.mysql
    • NAME——数据库名称
    • USER——数据库用户名
    • PASSWOD——数据库密码
    • HOST——数据库服务器地址
    • PORT——数据库端口地址
  3. 安装mysql数据的第三方模块

    pip install mysqlclient

  4. 在APP的models.py文件中创建实体类

    # 部门信息
    class Department(models.Model):
        name = models.CharField(max_length=100,verbose_name='部门名称')
        index = models.IntegerField(verbose_name='排序',null=True,blank=True)
        def __str__(self):
            return self.name
    
    # 员工信息
    class Employee(models.Model):
        name = models.CharField(max_length=100,verbose_name='姓名')
        depart = models.ForeignKey(to="Department", on_delete=models.CASCADE,verbose_name='部门')
        job_number = models.CharField(max_length=50,verbose_name='工号')
        gender_choices = (
            (1,'男'),
            (2,'女')
        )
        gender = models.IntegerField(choices=gender_choices,default=1,verbose_name='性别',null=True,blank=True)
        birthday = models.DateField(verbose_name='出生日期',null=True,blank=True)
        phone = models.CharField(max_length=11,verbose_name='手机号码',null=True,blank=True)
        email = models.EmailField(verbose_name='邮箱',null=True,blank=True)
        address = models.CharField(max_length=255,verbose_name='家庭住址',null=True,blank=True)
        nation = models.CharField(max_length=50,verbose_name='民族',null=True,blank=True)
        marital_choices = (
            (1,'已婚'),
            (2,'未婚')
        )
        marital = models.IntegerField(choices=marital_choices,default=2,verbose_name='婚姻状况',null=True,blank=True)
        id_number = models.CharField(max_length=18,verbose_name='身份证号',null=True,blank=True)
        hiredate = models.DateField(verbose_name='入职日期')
        rank = models.CharField(max_length=50,verbose_name='职级',null=True,blank=True)
        
    
    # 家庭成员
    class FamilyMember(models.Model):
        employee = models.ForeignKey(to="Employee", on_delete=models.CASCADE,verbose_name='员工ID')
        name = models.CharField(max_length=100,verbose_name='姓名')
        relationship_choices =(
            (1,'父子'),
            (2,'母子'),
            (3,'兄弟姐妹'),
            (4,'其他')
        )
        relationship = models.IntegerField(choices=relationship_choices,verbose_name='家人关系')
        phone = models.CharField(max_length=11,verbose_name='手机号码')
        address = models.CharField(max_length=255,verbose_name='家庭住址',null=True,blank=True)
    
  5. 确保APP已经在settings.py中进行了注册

  6. 在终端中执行命令进行数据表的创建

    python manage.py makemigrations          
    python manage.py migrate
    
    • makemigrations 准备好响应的SQL脚本
    • migrate 根据脚本执行SQL语句进行表的创建

数据模型创建基本语法

常用数据类型以及参数

  • CharField(max_length=最大长度) 字符串类型,参数max_length表示最大字符个数。

  • IntegerField整数类型字段。

  • DecimalField(max_digits=10,decimal_places=2)小数类型,参数max_digits表示总位数,decimal_places表示小数位数。

  • DateField([auto_now=False, auto_now_add=False])日期类型字段,其中:
    (1)auto_now表示每次保存对象时,自动设置该字段为当前时间,用于“最后一次修改”时间戳,默认为False
    (2)auto_now_add表示对象第一次被创建时自动设置当前时间,用于创建的时间戳,默认为False

  • DateTimeField 日期时间类型字段,参数同DateField

  • ForeignKey指定外键,对应一对多的关系。

    depart = models.ForeignKey(to="Department",to_field="id",on_delete=models.CASCADE,verbose_name='部门')
    
    • to——表示与哪个表关联
    • to_field——表示关联的字段
    • on_delete=models.CASCADE ——表示级联删除,部门表删除,对应的人员也删除
      • models.CASCADE:这是默认选项,意味着当父对象被删除时,与之关联的子对象也会被删除。
      • models.PROTECT:这个选项会阻止父对象的删除,如果存在与之关联的子对象。
      • models.SET_NULL:当父对象被删除时,将子对象的外键字段设置为 NULL。使用这个选项时,外键字段必须允许 NULL 值。
      • models.SET_DEFAULT:当父对象被删除时,将子对象的外键字段设置为默认值。外键字段必须有一个默认值。
      • models.DO_NOTHING:这个选项不会做任何事情,Django 不会尝试自动删除关联的子对象。
  • 选择性字段

    gender_choices = (
                    (1,'男'),
                    (2,'女')
        )
    gender = models.IntegerField(choices=gender_choices,default=1,verbose_name='性别')
    

    选择性字段的内容应该描述为元组类型,元组中第一个数为存放的数据,第二个为显示的内容

    choices参数指定选择器

常用公共参数

  • verbose_name 字段详细说明,重要一般都需要指定
  • default字段默认值,用于设置默认值约束。
  • null 数据库范畴,表示该字段允许为空
  • blank后台管理页面表单验证的范畴,表示该字段允许为空

class Meta内部类

通过定义Model的内部类,来添加数据模型的一些选项。

  • db_table属性允许自定义模型对应的数据库表名,遵循小写加下划线的命名规范,例如:
class Meta:
    db_table = 'sys_user'
  • ordering属性用于指定数据库排序依据,支持多个字段和升/降序排列。

    class Meta :
    	ordering = (' -publish',)
    
  • unique_together 属性指定两个字段组合起来是唯一性。

    class Meta :
        unique_together = (("ip", "port"),)
    

es`参数指定选择器

常用公共参数

  • verbose_name 字段详细说明,重要一般都需要指定
  • default字段默认值,用于设置默认值约束。
  • null 数据库范畴,表示该字段允许为空
  • blank后台管理页面表单验证的范畴,表示该字段允许为空

class Meta内部类

通过定义Model的内部类,来添加数据模型的一些选项。

  • db_table属性允许自定义模型对应的数据库表名,遵循小写加下划线的命名规范,例如:
class Meta:
    db_table = 'sys_user'
  • ordering属性用于指定数据库排序依据,支持多个字段和升/降序排列。

    class Meta :
    	ordering = (' -publish',)
    
  • unique_together 属性指定两个字段组合起来是唯一性。

    class Meta :
        unique_together = (("ip", "port"),)
    

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部