0


Django实践-03模型-01表生成模型+学科页面与教师页面编写

文章目录

在这里插入图片描述

Django实践-03模型

官网:https://www.djangoproject.com/
博客:https://www.liujiangblog.com/
git:https://gitcode.net/mirrors/jackfrued/Python-100-Days

Django静态文件问题备注:
参考:
Django测试开发-20-settings.py中templates配置,使得APP下的模板以及根目录下的模板均可生效
解决django 多个APP时 static文件的问题

Django MTV之模型

MVC架构中的“模型”和“视图”的解耦合。所谓“模型”就是数据(的表示),数据模型通常通过数据库实现持久化操作,而关系型数据库在过去和当下都是持久化的首选方案。

投票案例

下面我们通过完成一个投票项目来讲解和模型相关的知识点。

投票项目的首页会展示某在线教育平台所有的学科;
点击学科可以查看到该学科的老师及其信息;
用户登录后在查看老师的页面为老师投票,可以投赞成票和反对票;
未登录的用户可以通过登录页进行登录;
尚未注册的用户可以通过注册页输入个人信息进行注册。

在这个项目中,我们使用MySQL数据库来实现数据持久化操作。

1.创建应用

1.创建应用

注意执行的位置,要在djangoproject的目录下执行

  1. django-admin startapp polls

2.配置模板文件

在templates目录下

登录页面login.html
注册页面register.html,

创建templates/polls目录。在polls目录下创建

展示学科的页面subjects.html
显示学科老师的页面teachers.html

具体内容下文进行描述。

2.配置关系型数据库MySQL

1.创建数据库

  1. 在MySQL中创建数据库,创建用户,授权用户访问该数据库。
  1. createdatabase vote defaultcharset utf8;createuser'django'@'%' identified by'django123';grantallprivilegeson vote.*to'django'@'%';
  2. flush privileges;

2.创建表

  1. 在MySQL中创建保存学科和老师信息的二维表(保存用户信息的表稍后处理)。
  1. use vote;-- 创建学科表createtable`tb_subject`(`no`integerauto_incrementcomment'学科编号',`name`varchar(50)notnullcomment'学科名称',`intro`varchar(1000)notnulldefault''comment'学科介绍',`is_hot`booleannotnulldefault0comment'是不是热门学科',primarykey(`no`));-- 创建老师表createtable`tb_teacher`(`no`integerauto_incrementcomment'老师编号',`name`varchar(20)notnullcomment'老师姓名',`sex`booleannotnulldefault1comment'老师性别',`birth`datenotnullcomment'出生日期',`intro`varchar(1000)notnulldefault''comment'老师介绍',`photo`varchar(255)notnulldefault''comment'老师照片',`gcount`integernotnulldefault0comment'好评数',`bcount`integernotnulldefault0comment'差评数',`sno`integernotnullcomment'所属学科',primarykey(`no`),foreignkey(`sno`)references`tb_subject`(`no`));

3.按照MySQL依赖

在虚拟环境中安装连接MySQL数据库所需的依赖项。

  1. pip install mysqlclient -i https://pypi.tuna.tsinghua.edu.cn/simple

4.修改settings.py文件 添加应用 配置数据库

修改项目的settings.py文件,首先将我们创建的应用polls添加已安装的项目(INSTALLED_APPS)中,然后配置MySQL作为持久化方案。

  1. INSTALLED_APPS =[# 新增polls'polls',]
  2. DATABASES ={'default':{# 数据库引擎配置'ENGINE':'django.db.backends.mysql',# 数据库的名字'NAME':'vote',# 数据库服务器的IP地址(本机可以写localhost127.0.0.1'HOST':'localhost',# 启动MySQL服务的端口号'PORT':3306,# 数据库用户名和口令'USER':'django','PASSWORD':'django123',# 数据库使用的字符集'CHARSET':'utf8',# 数据库时间日期的时区设定'TIME_ZONE':'Asia/Shanghai',}}

在配置ENGINE属性时,常用的可选值包括:sqlite3,postgresql,oracle,mysql

5. 基于数据库生成实体类

Django框架提供了ORM来解决数据持久化问题,ORM翻译成中文叫“对象关系映射”。利用Django的ORM,我们可以直接将刚才创建的学科表和老师表变成Django中的模型类。

  1. python manage.py inspectdb > polls/models.py

在polls/models.py中生成如下代码,我们可以修改实体类,

  1. from django.db import models
  2. # Create your models here.# This is an auto-generated Django model module.# You'll have to do the following manually to clean this up:# * Rearrange models' order# * Make sure each model has one field with primary_key=True# * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table# Feel free to rename the models, but don't rename db_table values or field names.# 添加了注释部分verbose_name="名称"classSubject(models.Model):# TbSubject 修改为 Subject
  3. no = models.AutoField(primary_key=True,verbose_name="编号")
  4. name = models.CharField(max_length=50,verbose_name="名称")
  5. intro = models.CharField(max_length=1000,verbose_name="介绍")
  6. is_hot = models.IntegerField(verbose_name="是否热门")classMeta:
  7. managed =False
  8. db_table ='tb_subject'classTeacher(models.Model):# TbTeacher修改为Teacher
  9. no = models.AutoField(primary_key=True,verbose_name="编号")
  10. name = models.CharField(max_length=20,verbose_name="教师姓名")
  11. sex = models.IntegerField(verbose_name="性别")
  12. birth = models.DateField(verbose_name="出生年月")
  13. intro = models.CharField(max_length=1000,verbose_name="个人介绍")
  14. photo = models.CharField(max_length=255,verbose_name="照片")
  15. good_count = models.IntegerField(db_column="gcount",verbose_name="好评数")# gcount 修改为good_count
  16. bad_count= models.IntegerField(db_column="bcount",verbose_name="差评数")# bcount 修改为bad_count 添加db_column
  17. subject = models.ForeignKey(Subject, models.DO_NOTHING, db_column='sno')# sno 修改为 subject, TbSubject修改为SubjectclassMeta:
  18. managed =False
  19. db_table ='tb_teacher'

3.使用ORM完成模型的CRUD操作

在终端中输入下面的命令进入到Django项目的交互式环境,然后尝试对模型的操作。

  1. python manage.py shell
1.新增
  1. from polls.models import Subject,Teacher
  2. subject1 = Subject(name='Python全栈开发', intro='当下最热门的学科', is_hot=True)
  3. subject1.save()
  4. subject2 = Subject(name='全栈软件测试', intro='学习自动化测试的学科', is_hot=False)
  5. subject2.save()
  6. subject3 = Subject(name='JavaEE分布式开发', intro='基于Java语言的服务器应用开发', is_hot=True)
  7. subject3.save()

在这里插入图片描述

  1. subject = Subject.objects.get(no=1)
  2. t1 = Teacher(name='甲1', sex="1",birth="2000-05-02",photo="照片路径",good_count="11",bad_count="0",intro='数学老师', subject=subject )
  3. t1.save()

在这里插入图片描述

  1. subject = Subject.objects.get(no=3)
  2. t2 = Teacher(name='丙3', sex="2",birth="2000-05-02",photo="照片路径",good_count="11",bad_count="0",intro='语文老师', subject=subject )
  3. t2.save()

在这里插入图片描述

  1. subject = Subject.objects.get(no=1)
  2. t3 = Teacher(name='丁4', sex="1",birth="2000-05-02",photo="照片路径",good_count="11",bad_count="0",intro='计算机老师', subject=subject )
  3. t3.save()

在这里插入图片描述

2.删除
  1. subject = Subject.objects.get(no=2)
  2. subject.delete()# (1, {'polls.Subject': 1})
3.更新
  1. subject = Subject.objects.get(no=1)
  2. subject.name ='Python全栈+人工智能'
  3. subject.save()

在这里插入图片描述

4.查询
  1. 查询所有对象。
  1. Subject.objects.all()# <QuerySet [<Subject: Subject object (1)>, <Subject: Subject object (3)>]>
  1. 过滤数据。
  1. # 查询名称为“Python全栈+人工智能”的学科
  2. Subject.objects.filter(name='Python全栈+人工智能')# <QuerySet [<Subject: Subject object (1)>]># 查询名称包含“全栈”的学科(模糊查询)
  3. Subject.objects.filter(name__contains='全栈')# <QuerySet [<Subject: Subject object (1)>]>
  4. Subject.objects.filter(name__startswith='全栈')# <QuerySet []>
  5. Subject.objects.filter(name__endswith='全栈')# <QuerySet []># 查询所有热门学科
  6. Subject.objects.filter(is_hot=True)# <QuerySet [<Subject: Subject object (1)>, <Subject: Subject object (3)>]># 查询编号大于3小于10的学科
  7. Subject.objects.filter(no__gt=3).filter(no__lt=10)# <QuerySet []>
  8. Subject.objects.filter(no__gt=3, no__lt=10)# <QuerySet []># 查询编号在37之间的学科
  9. Subject.objects.filter(no__gte=3, no__lte=7)# <QuerySet [<Subject: Subject object (3)>]>
  10. Subject.objects.filter(no__range=(3,7))# <QuerySet [<Subject: Subject object (3)>]>
  1. 查询单个对象。
  1. # 查询主键为1的学科
  2. Subject.objects.get(pk=1)# <Subject: Subject object (1)>
  3. Subject.objects.get(no=1)# <Subject: Subject object (1)>
  4. Subject.objects.filter(no=1).first()# <Subject: Subject object (1)>
  5. Subject.objects.filter(no=1).last()# <Subject: Subject object (1)>
  1. 排序。
  1. # 查询所有学科按编号升序排列
  2. Subject.objects.order_by('no')# <QuerySet [<Subject: Subject object (1)>, <Subject: Subject object (3)>]># 查询所有部门按部门编号降序排列
  3. Subject.objects.order_by('-no')# <QuerySet [<Subject: Subject object (3)>, <Subject: Subject object (1)>]>
  1. 切片(分页查询)。
  1. # 按编号从小到大查询前3个学科
  2. Subject.objects.order_by('no')[:3]# <QuerySet [<Subject: Subject object (1)>, <Subject: Subject object (3)>]>
  1. 计数。
  1. # 查询一共有多少个学科
  2. Subject.objects.count()# 2
  1. 高级查询。
  1. # 查询编号为1的学科的老师
  2. Teacher.objects.filter(subject__no=1)# <QuerySet [<Teacher: Teacher object (1)>, <Teacher: Teacher object (3)>]>
  3. Subject.objects.get(pk=1).teacher_set.all()# Subject.objects.get(pk=1).teacher_set.all() # 查询学科名称有“全栈”二字的学科的老师
  4. Teacher.objects.filter(subject__name__contains='全栈')# <QuerySet [<Teacher: Teacher object (1)>, <Teacher: Teacher object (3)>]>

说明1:由于老师与学科之间存在多对一外键关联,所以能通过学科反向查询到该学科的老师(从一对多关系中“一”的一方查询“多”的一方),反向查询属性默认的名字是类名小写_set(如上面例子中的teacher_set),当然也可以在创建模型时通过ForeingKey的related_name属性指定反向查询属性的名字。如果不希望执行反向查询可以将related_name属性设置为’+‘或者以’+'开头的字符串。
说明2:ORM查询多个对象时会返回QuerySet对象,QuerySet使用了惰性查询,即在创建QuerySet对象的过程中不涉及任何数据库活动,等真正用到对象时(对QuerySet求值)才向数据库发送SQL语句并获取对应的结果,这一点在实际开发中需要引起注意!
说明3:如果希望更新多条数据,不用先逐一获取模型对象再修改对象属性,可以直接使用QuerySet对象的update()方法一次性更新多条数据。

3.实现学科页和老师页效果

修改polls/views.py文件,编写视图函数实现对学科页和老师页的渲染。

  1. from django.shortcuts import render, redirect
  2. from polls.models import Subject, Teacher
  3. defshow_subjects(request):
  4. subjects = Subject.objects.all().order_by('no')return render(request,'polls/subjects.html',{'subjects': subjects})defshow_teachers(request):try:
  5. sno =int(request.GET.get('sno'))
  6. teachers =[]if sno:
  7. subject = Subject.objects.only('name').get(no=sno)
  8. teachers = Teacher.objects.filter(subject=subject).order_by('no')return render(request,'polls/teachers.html',{'subject': subject,'teachers': teachers
  9. })except(ValueError, Subject.DoesNotExist):return redirect('/')

创建header.html文件

接下来我们可以稍微对首页的代码进行调整,在页面的右上角显示出登录用户的用户名。我们将这段代码单独写成了一个名为polls/templates/header.html的HTML文件,首页中可以通过在<body>标签中添加{% include ‘header.html’ %}来包含这个页面,代码如下所示。

  1. <divclass="user">
  2. {% if request.session.userid %}
  3. <span>{{ request.session.username }}</span><ahref="/logout">注销</a>
  4. {% else %}
  5. <ahref="/login">登录</a>&nbsp;&nbsp;
  6. {% endif %}
  7. <ahref="/register">注册</a></div>

修改templates/subjects.html和templates/teachers.html模板页。

subjects.html

  1. <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>学科信息</title><style>#container{width: 80%;margin: 10px auto;}.user{float: right;margin-right: 10px;}.user>a{margin-right: 10px;}#main>dl>dt{font-size: 1.5em;font-weight: bold;}#main>dl>dd{font-size: 1.2em;}a{text-decoration: none;color: darkcyan;}</style></head><body>
  2. {% include 'header.html' %}
  3. <divid="container"><!-- <div class="user">
  4. <a href="/login">用户登录</a>
  5. <a href="/register">快速注册</a>
  6. </div> --><h1>XX学堂所有学科</h1><hr><ahref="/excel">教师信息下载</a><divid="main">
  7. {% for subject in subjects %}
  8. <dl><dt><ahref="/teachers/?sno={{ subject.no }}">{{ subject.name }}</a>
  9. {% if subject.is_hot %}
  10. <imgsrc="/static/images/hot-icon-small.png">
  11. {% endif %}
  12. </dt><dd>{{ subject.intro }}</dd></dl>
  13. {% endfor %}
  14. </div></div></body></html>

teachers.html

  1. <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>老师信息</title><style>#container{width: 80%;margin: 10px auto;}.teacher{width: 100%;margin: 0 auto;padding: 10px 0;border-bottom: 1px dashed gray;overflow: auto;}.teacher>div{float: left;}.photo{height: 140px;border-radius: 75px;overflow: hidden;margin-left: 20px;}.info{width: 75%;margin-left: 30px;}.info div{clear: both;margin: 5px 10px;}.info span{margin-right: 25px;}.info a{text-decoration: none;color: darkcyan;}</style></head><body>
  2. {% include 'header.html' %}
  3. <ahref="/get_echarts">教师好评分析</a><divid="container"><h1>{{ subject.name }}学科的老师信息</h1><hr>
  4. {% if not teachers %}
  5. <h2>暂无该学科老师信息</h2>
  6. {% endif %}
  7. {% for teacher in teachers %}
  8. <divclass="teacher"><divclass="photo"><imgsrc="/static/images/{{ teacher.photo }}"height="140"alt=""></div><divclass="info"><div><span><strong>姓名:{{ teacher.name }}</strong></span><span>性别:{{ teacher.sex | yesno:'男,女' }}</span><span>出生日期:{{ teacher.birth }}</span></div><divclass="intro">{{ teacher.intro }}</div><divclass="comment"><ahref="/praise/?tno={{ teacher.no }}">好评</a>&nbsp;&nbsp;
  9. (<strong>{{ teacher.good_count }}</strong>)
  10. &nbsp;&nbsp;&nbsp;&nbsp;<ahref="/criticize/?tno={{ teacher.no }}">差评</a>&nbsp;&nbsp;
  11. (<strong>{{ teacher.bad_count }}</strong>)
  12. </div></div></div>
  13. {% endfor %}
  14. <ahref="/">返回首页</a></div><scriptsrc="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script><script>$(()=>{$('.comment>a').on('click',(evt)=>{
  15. evt.preventDefault()let url =$(evt.target).attr('href')
  16. $.getJSON(url,(json)=>{if(json.code ==20000){$(evt.target).next().text(json.count)}else{alert(json.mesg)}})})})</script></body></html>

修改vote/urls.py文件,实现映射URL。

  1. from django.contrib import admin
  2. from django.urls import path
  3. from polls import views as polls_views
  4. urlpatterns =[
  5. path('admin/', admin.site.urls),
  6. path('', polls_views.show_subjects),
  7. path('teachers/', polls_views.show_teachers),]

到此为止,页面上需要的图片(静态资源)还没有能够正常展示,我们在下一章节中为大家介绍如何处理模板页上的需要的静态资源。

运行测试

  1. python manage.py runserver

在这里插入图片描述

在这里插入图片描述

总结

本文主要是Django系列博客。本文是Django模型层models的使用过程。
1.创建数据库
2.创建表
3.按照MySQL依赖
4.修改settings.py文件,添加应用配置数据库
5.基于数据库生成实体类
6.使用shell完成CRUD操作

标签: django python 后端

本文转载自: https://blog.csdn.net/m0_38139250/article/details/129280649
版权归原作者 IT从业者张某某 所有, 如有侵权,请联系我们删除。

“Django实践-03模型-01表生成模型+学科页面与教师页面编写”的评论:

还没有评论