关于orm 的基础3 day67

时间:2022-06-24 07:09:31
day67

ORM

特殊的语法
一个简单的语法 --翻译成--> SQL语句 语法:
1. 操作数据库表 创建表、删除表、修改表 2. 操作数据库行 增、删、改、查 怎么连数据库:
需要手动创建数据库
手写一段代码
告诉Django连哪个数据库
告诉Django用pymysql代替默认的MySQLdb
发命令:
python manage.py makemigrations
python manage.py migrate 总结详细步骤:
1. 手动创建数据库
2. 在app/models.py里面写上一个类,必须继承models.Model这个类 (注意启动Django项目)
3. 在Django 项目的settings.py 里面 配置上数据库的相关信息
4. 在Django项目里的__init__.py里面写上 两句话 import pymysql pymysql.install_as_MySQLdb()
5. 给Django发布命令
1. python manage.py makemigrations # 相当于去你的models.py 里面看一下有没有改动
2. python manage.py migrate # 把改动翻译成SQL语句,然后去数据库执行 models.py --> Django翻译成SQL --> pymysql --> MySQL(4p) 哪吒老师ORM思想:
五步四部分 目前为止学到的特殊语法之操作数据表部分:
1. 通过建一个类(继承models.Model) --> 相当于创建了一个数据库中的表 --> 类 - 数据表
2. 字段:
1. models.AutoField(primary_key=True) --> int 自增的 主键
2. models.CharField(max_length=32, null=True) --> varchar(32)
3. models.IntegerField() # int 总结一下:
models.py MySQL
类 对应 数据表
类的属性 对应 数据库里面的字段(列)
对象 对应 一行数据(一条数据) ORM到底是什么? 对象关系映射 数据行的操作:
增:两种
1. models.User.objects.create(**{}) 直接创建并且提交到数据库
2. user = models.User(**{}) user.save() 删:
找到对象删除
models.User.objects.filter().delete() 改:
更新 两种
1. models.User.objects.filter().update(username="一枝花")
2. user = models.User.objects.get(id=1) user.username="梁志华" user.save() 查:
models.User.objects.all()
models.User.objects.get(条件) 不满足条件就报错|返回的是一个对象
models.User.objects.filter(条件) 不满足条件不报错,但是返回的结果是一个对象的列表
models.User.objects.filter().first()
models.User.objects.filter().last() models.User.objects.exclude(条件)

orm结构笔记

Django之ORM的含义

O-->object

R--->relational(链接)

M--->mapping(映射)

orm介绍

orm概念

对象映射关系模式是一种为了解决面相对象与关系数据库存在的互不匹配的现象的技术

,简单来说orm是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动化持久关旭数据库中.orm在业务逻辑层和数据层之间充当了桥梁的作用

我们的数据库操作相对比较复杂,我们在django框架的基础上,使用的这个orm就可以在不使用数据库的基础上,对数据库里面的信息进行操作,执行起来更加的简单,便捷,

orm由来

我们的所有软件开发过程中都是会涉及到对象和关系数据库在用户层面和业务逻辑层面我们是面相对象的,当对象的信息发生变化的时候我们需要把对象的信息保存到关系数据库中

按照之前的方法来进行开发就会出现程序员自己的业务逻辑代码中夹杂着很多的sql语句来增加,读取,修改和删除相关数据,而这些代码通常都是重复的,

orm的优势

它主要问题是解决关系的映射,它通常把一个类和一个表一一对应

类的每个实例对应表中的一条数据,类的每个属性对应表中的每个字段

orm提供了对数据库的映射,不用直接编写sql语句,只需要像操作对象一样从数据库里操作数据,让发开发人员专注于开发自己的业务逻辑处理,提高了开发效率

orm的劣势

orm的缺点是会在一定程度上牺牲程序员的执行效率,而且用得多了以后我们就会忘记sql语句如何写了,关系数据库的相关技能会退化...所有的自动化机制都是这样的,把人力从繁杂的劳动中解放出来然后相关的技能呢就会退化,就会更加的依赖于机器,或者更加便捷的程序,就像我们的机器人总动员一样,剧中最后船长甚至没有*行走的能力都是因为过度依赖于过分便捷的机器导致的.

orm总结,

orm只是一种工具,工具确实能够解决一些重复简单的劳动,这是不可否认的.

但我们不能指望某个工具一劳永逸地解决所有问题,一些特殊问题还是需要特殊处理的,

但是在整个软件开发过程中需要特殊处理的情况应该都是很少的,否则所谓的工具也就失去了它存在的意义.

model

model是django中数据的单一明确的信息来源,它包含了你所存储的数据的重要字段,和行为,通常一个模型model映射到一个数据表格

基本情况:

每个模型都是一个python类,它是django.db.model的子类

模型的每个属性都代表了一个数据库字段

综上所述,django为您提供了一个自动生成的数据库访问api,

表格的名字是自动生成的,如果你要自定义表名,需要在model的Meta类中定义db_table参数,一般会写成小写的表名,格式就是在我们定义好的类和类属性下面,如下所示:

class Pupil(models.Model):
id = models.AutoField(primary_key=True) #自增id
sname = models.CharField(max_length=30, null=True) #相当vachar
age = models.IntegerField(null=True) #int 默认为空
# cid = models.IntegerField()
class Meta:
db_table = 'pupil'
通过django 类名是前面有前缀 但是这么些名字会改变没有后缀
 AutoField(Field)
- int自增列,必须填入参数 primary_key=True BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True 注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models class UserInfo(models.Model):
# 自动创建一个列名为id的且为自增的整数列
username = models.CharField(max_length=32) class Group(models.Model):
# 自定义自增列
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32) SmallIntegerField(IntegerField):
- 小整数 -32768 ~ 32767 PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767
IntegerField(Field)
- 整数列(有符号的) -2147483648 ~ 2147483647 PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647 BigIntegerField(IntegerField):
- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807 BooleanField(Field)
- 布尔值类型 NullBooleanField(Field):
- 可以为空的布尔值 CharField(Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度 TextField(Field)
- 文本类型 EmailField(CharField):
- 字符串类型,Django Admin以及ModelForm中提供验证机制 IPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制 GenericIPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
- 参数:
protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both" URLField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证 URL SlugField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号) CommaSeparatedIntegerField(CharField)
- 字符串类型,格式必须为逗号分割的数字 UUIDField(Field)
- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证 FilePathField(Field)
- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹 FileField(Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage ImageField(FileField)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串) DateTimeField(DateField)
- 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField(DateTimeCheckMixin, Field)
- 日期格式 YYYY-MM-DD TimeField(DateTimeCheckMixin, Field)
- 时间格式 HH:MM[:ss[.uuuuuu]] DurationField(Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型 FloatField(Field)
- 浮点型 DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度 BinaryField(Field)
- 二进制类型

常用字段

class UnsignedIntegerField(models.IntegerField):
def db_type(self, connection):
return 'integer UNSIGNED' PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
'AutoField': 'integer AUTO_INCREMENT',
'BigAutoField': 'bigint AUTO_INCREMENT',
'BinaryField': 'longblob',
'BooleanField': 'bool',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'DurationField': 'bigint',
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'IntegerField': 'integer',
'BigIntegerField': 'bigint',
'IPAddressField': 'char(15)',
'GenericIPAddressField': 'char(39)',
'NullBooleanField': 'bool',
'OneToOneField': 'integer',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time',
'UUIDField': 'char(32)', 自定义一个无符号整数字段

自定义字段

 class FixedCharField(models.Field):
"""
自定义的char类型的字段类
"""
def __init__(self, max_length, *args, **kwargs):
self.max_length = max_length
super(FixedCharField, self).__init__(max_length=max_length, *args, **kwargs) def db_type(self, connection):
"""
限定生成数据库表的字段类型为char,长度为max_length指定的值
"""
return 'char(%s)' % self.max_length class Class(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=25)
# 使用自定义的char类型的字段
cname = FixedCharField(max_length=25)
复制代码

自定义char字段

 1.触发Model中的验证和错误提示有两种方式:
a. Django Admin中的错误信息会优先根据Admiin内部的ModelForm错误信息提示,如果都成功,才来检查Model的字段并显示指定错误信息
b. 使用ModelForm
c. 调用Model对象的 clean_fields 方法,如:
# models.py
class UserInfo(models.Model):
nid = models.AutoField(primary_key=True)
username = models.CharField(max_length=32) email = models.EmailField(error_messages={'invalid': '格式错了.'}) # views.py
def index(request):
obj = models.UserInfo(username='', email='uu')
try:
print(obj.clean_fields())
except Exception as e:
print(e)
return HttpResponse('ok') # Model的clean方法是一个钩子,可用于定制操作,如:上述的异常处理。 2.Admin中修改错误提示
# admin.py
from django.contrib import admin
from model_club import models
from django import forms class UserInfoForm(forms.ModelForm):
age = forms.IntegerField(initial=1, error_messages={'required': '请输入数值.', 'invalid': '年龄必须为数值.'}) class Meta:
model = models.UserInfo
# fields = ('username',)
fields = "__all__"
exclude = ['title']
labels = { 'name':'Writer', }
help_texts = {'name':'some useful help text.',}
error_messages={ 'name':{'max_length':"this writer name is too long"} }
widgets={'name':Textarea(attrs={'cols':80,'rows':20})} class UserInfoAdmin(admin.ModelAdmin):
form = UserInfoForm admin.site.register(models.UserInfo, UserInfoAdmin)

字段注意

 null                数据库中字段是否可以为空
db_column 数据库中字段的列名
default 数据库中字段的默认值
primary_key 数据库中字段是否为主键
db_index 数据库中字段是否可以建立索引
unique 数据库中字段是否可以建立唯一索引
unique_for_date 数据库中字段【日期】部分是否可以建立唯一索引
unique_for_month 数据库中字段【月】部分是否可以建立唯一索引
unique_for_year 数据库中字段【年】部分是否可以建立唯一索引 verbose_name Admin中显示的字段名称
blank Admin中是否允许用户输入为空
editable Admin中是否可以编辑
help_text Admin中该字段的提示信息
choices Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1) error_messages 自定义错误信息(字典类型),从而定制想要显示的错误信息;
字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
如:{'null': "不能为空.", 'invalid': '格式错误'} validators 自定义错误验证(列表类型),从而定制想要的验证规则
from django.core.validators import RegexValidator
from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
如:
test = models.CharField(
max_length=32,
error_messages={
'c1': '优先错信息1',
'c2': '优先错信息2',
'c3': '优先错信息3',
},
validators=[
RegexValidator(regex='root_\d+', message='错误了', code='c1'),
RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'),
EmailValidator(message='又错误了', code='c3'), ]

字段的参数

# 增
models.Tb1.objects.create(c1='xx', c2='oo') # 增加一条数据,可以接受字典类型数据 **kwargs
obj = models.Tb1(c1='xx', c2='oo')
obj.save() # 查
models.Tb1.objects.get(id=123) # 获取单条数据,不存在则报错(不建议)
models.Tb1.objects.all() # 获取全部
models.Tb1.objects.filter(name='seven') # 获取指定条件的数据
models.Tb1.objects.exclude(name='seven') # 去除指定条件的数据 # 删
# models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据 # 改
models.Tb1.objects.filter(name='seven').update(gender='') # 将指定条件的数据更新,均支持 **kwargs
obj = models.Tb1.objects.get(id=1)
obj.c1 = ''
obj.save() # 修改单条数据

orm 的操作

# 获取个数
#
# models.Tb1.objects.filter(name='seven').count() # 大于,小于
#
# models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值
# models.Tb1.objects.filter(id__gte=1) # 获取id大于等于1的值
# models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值
# models.Tb1.objects.filter(id__lte=10) # 获取id小于10的值
# models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值 # in
#
# models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
# models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in # isnull
# Entry.objects.filter(pub_date__isnull=True) # contains
#
# models.Tb1.objects.filter(name__contains="ven")
# models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
# models.Tb1.objects.exclude(name__icontains="ven") # range
#
# models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and # 其他类似
#
# startswith,istartswith, endswith, iendswith, # order by
#
# models.Tb1.objects.filter(name='seven').order_by('id') # asc
# models.Tb1.objects.filter(name='seven').order_by('-id') # desc # group by
#
# from django.db.models import Count, Min, Max, Sum
# models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
# SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id" # limit 、offset
#
# models.Tb1.objects.all()[10:20] # regex正则匹配,iregex 不区分大小写
#
# Entry.objects.get(title__regex=r'^(An?|The) +')
# Entry.objects.get(title__iregex=r'^(an?|the) +') # date
#
# Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
# Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1)) # year
#
# Entry.objects.filter(pub_date__year=2005)
# Entry.objects.filter(pub_date__year__gte=2005) # month
#
# Entry.objects.filter(pub_date__month=12)
# Entry.objects.filter(pub_date__month__gte=6) # day
#
# Entry.objects.filter(pub_date__day=3)
# Entry.objects.filter(pub_date__day__gte=3) # week_day
#
# Entry.objects.filter(pub_date__week_day=2)
# Entry.objects.filter(pub_date__week_day__gte=2) # hour
#
# Event.objects.filter(timestamp__hour=23)
# Event.objects.filter(time__hour=5)
# Event.objects.filter(timestamp__hour__gte=12) # minute
#
# Event.objects.filter(timestamp__minute=29)
# Event.objects.filter(time__minute=46)
# Event.objects.filter(timestamp__minute__gte=29) # second
#
# Event.objects.filter(timestamp__second=31)
# Event.objects.filter(time__second=2)
# Event.objects.filter(timestamp__second__gte=31)

orm 进阶

orm 的增删改查 班级 学生老师表

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学生表</title>
</head>
<body>
<div><h>学生表</h></div> <table border="" style="color: #2aabd2">
<thead>
<tr>
<th>序号</th>
<th>学生ID</th>
<th>学生名字</th>
<th>学生信息</th>
<th>所在班级</th> </tr>
</thead>
<tbody>
{% for student in st_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ student.id }}</td>
<td>{{ student.sname }}</td>
<td>{{ student.detail_id}}</td>
<td>{{ student.cid_id}}</td>
<td>
{# 通过get 方法取值的#}
{# <a href="/app0001/edit_student_list/?student_id={{ student.id }}" style="color:blue ; text-decoration: none">编辑</a>#}
{# 通过分组的方法取值的#}
<a href="{% url 'app0001urls:editstudentlist' student.id %}" style="color:blue ; text-decoration: none">编辑</a>
<a href="{% url 'app0001urls:deletestudentlist' student.id %}" style="color:blue ; text-decoration: none">删除</a>
</td>
</tr>
{% endfor %}
<tr>
<a href="/app0001/add_student_list/" style="color:red ; text-decoration: none">添加</a>
</tr>
</tbody> </table> </body>
</html>

student 展示表单

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>老师表</title>
</head>
<body> <table border="">
<thead>
<tr>
<th>序号</th>
<th>老师ID</th>
<th>老师姓名</th>
<th>授课班级</th>
</tr>
</thead>
<tbody>
{#teacher_list 取到所有的老师#}
{% for teacher in teacher_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ teacher.id }}</td>
<td>{{ teacher.tname }}</td>
{# 授课班级的展示 老师的#}
<td>
{# 注意注意 ?????这里cid #}
{# teacher.cid.all 在html不用加上括号是什么 意思就是每个 #}
{% for class in teacher.cid.all %}
{{ class.cname }}
{% endfor %}
</td> <td>
<a href="{% url 'app0001urls:deleteteacherlist' teacher.id %}">删除</a>
<a href="{% url 'app0001urls:editteacherlist' teacher.id %}">编辑</a>
</td> </tr>
{% endfor %} {# 这里注意网址 因为django 项目已经开启子项目的命名#}
<a href="{% url 'app0001urls:addteacherlist'%}">添加</a>
{# <a href="{% url 'app0001urls:addteacherlist'%}">添加</a>#}
{# <tr><a href="/app0001/add_class_list/">添加</a></tr>#}
{# <tr><a href="{% url 'app0001urls:addclasslist' %}">添加</a></tr>#} </tbody> </table> </body>
</html>

teacher 展示表单

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>老师表</title>
</head>
<body> <form action="{% url 'app0001urls:addteacherlist' %}" method="post" >
{# 这个不需要去settings 注释了#}
{% csrf_token %}
{# <input type="text" name="class_id" style="display: none">#}
老师姓名<input type="text" name="teacher_name"> {# multiple 说明是多选#} <label for="t_id"></label>
{# name 对应的value 是提交的值此时的id是多个 因为是个多选 #}
<select name="class_id" id="t_id" multiple>授课班级
{% for class in class_list %}
<option value="{{ class.id }}">{{ class.cname }}</option>
{% endfor %}
</select>
<input type="submit" value="提交">
<input type="submit" value="取消">
</form> </body>
</html>

teacher的增加


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>班级表</title>
</head>
<body> {#这里的form 表单里因为url 那里已经分组 必须是两个参数组成的url action 必须是两部分e_name1.id 就是那个\d+#}
<form action="{% url 'app0001urls:editclasslist' e_name1.id %}" method="post" >
{% csrf_token %}
{# id这里必须要有id的值为什么 因为POST 通过id的name 取值 他的值就是现在的value#}
<input type="text" name="class_id" value="{{ e_name1.id }}" style="display: none">
班级名称<input type="text" name="class_name" value='{{ e_name1.cname }}'>
{# 时间的类型注意#}
开班时间<input type="date" name="first_day" value='{{ e_name1.first_day|date:'Y-m-d'}}'>
<input type="submit" value="提交">
<a href="/app0001/class_list/">取消</a>
</form> </body>
</html>

class 的编辑

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑学生表</title>
</head>
<body>
{#别名返乡解析分组 通过分组 url 参数两个 这里也要了两个 不传也行 但是考虑网址变化#}
{#e_name1.id 是编辑 通过分组拿到的arg 的值#}
<form action="{% url 'app0001urls:editstudentlist' e_svalue1.id %}" method= "post">
{% csrf_token %}
<div>
<input type="text" name="s_id" value="{{ e_svalue1.id }}" style="display: none">
学生姓名<input type="text" name="s_name" value="{{ e_svalue1.sname }}">
</div>
<div>所在班级
<label for="class_id"></label>
<select name="class_name" id="class_id">
{% for class in class_list %}
{# 编辑的默认值 判断操作 开始{% ifXX %} {% else %}结束{% endif %}#}
{% if e_svalue1.id == class.id %}
<option selected value="{{ class.id }}">{{ class.cname }}</option>
{% else %}
<option value="{{ class.id }}">{{ class.cname }}</option>
{% endif %}
{% endfor %}
</select> </div> <div>
<input type="submit" value="取消">
<input type="submit" value="提交">
</div> </form> </body>
</html>

student 的编辑

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑老师表</title>
</head>
<body>
{#别名返乡解析分组 通过分组 url 参数两个 这里也要了两个 不传也行 但是考虑网址变化#}
{#e_name1.id 是编辑 通过分组拿到的arg 的值#} <form action="{% url 'app0001urls:editteacherlist' teacher_id.id %}" method="post">
{% csrf_token %}
老师姓名<input type="text" name="teacher_name" value="{{ teacher_id.tname }}">
<label for="t_id"></label>
授课班级<select name="class_id" id="t_id" multiple>
{% for class in class_list %}
{# 注意此处 如果这个班级在点击编辑老师的cid表中取得的所有对象中 .all 在html 不要加括号#}
{% if class in teacher_id.cid.all %}
<option selected value="{{ class.id }}">{{ class.cname }}</option>
{% else %}
<option value="{{ class.id }}">{{ class.cname }}</option>
{% endif %}
{% endfor %}
</select>
<div>
<input type="submit" value="取消">
<input type="submit" value="提交">
</div>
</form> {# <form action="{% url 'app0001urls:editteacherlist' %}" method= "post">#}
{##}
{# <div>#}
{# <input type="text" name="s_id" value="{{ e_svalue1.id }}" style="display: none">#}
{# 学生姓名<input type="text" name="s_name" value="{{ e_svalue1.sname }}">#}
{# </div>#}
{# <div>所在班级#}
{# <label for="class_id"></label>#}
{# <select name="class_name" id="class_id">#}
{# {% for class in class_list %}#}
{# 编辑的默认值 判断操作 开始{% ifXX %} {% else %}结束{% endif %}#}
{# {% if e_svalue1.id == class.id %}#}
{# <option selected value="{{ class.id }}">{{ class.cname }}</option>#}
{# {% else %}#}
{# <option value="{{ class.id }}">{{ class.cname }}</option>#}
{# {% endif %}#}
{# {% endfor %}#}
{# </select>#}
{##}
{# </div>#}
{##}
{# <div>#}
{# <input type="submit" value="取消">#}
{# <input type="submit" value="提交">#}
{# </div>#}
{##}
{#</form>#} </body>
</html>

teacher 的编辑

from django.shortcuts import render,redirect,HttpResponse
from app0001 import models
from django.urls import reverse
# Create your views here.
# 建表 添加数据库到页面
def class_list(request):
class_list = models.Ban_list.objects.all()
# add_class_list = models.Ban_list.objects.create(cname='Python 1期',)
# add_class_list = models.Ban_list.objects.create(cname='Python 2期',)
# add_class_list = models.Ban_list.objects.create(cname='Python 3期',)
# add_class_list = models.Ban_list.objects.create(cname='Python 4期',)
# add_class_list = models.Ban_list.objects.create(cname='Python 5期',)
# add_class_list = models.Ban_list.objects.create(cname='Linux 1期',)
# add_class_list = models.Ban_list.objects.create(cname='Linux 2期',)
# add_class_list = models.Ban_list.objects.create(cname='Linux 3期',)
# add_class_list = models.Ban_list.objects.create(cname='Linux 4期',)
# 增加
# class1= models.Ban_list.objects.create(cname='Java 1期')
# 删除
# models.Ban_list.objects.filter(id=11).delete()
# 改i
# models.Ban_list.objects.filter(id=10).update(cname='大数据1期')
# 查找
# models.Ban_list.objects.all
# c1=models.Ban_list.objects.get(id=5)
# c1 = models.Ban_list.objects.filter(id=5)
# c1 = models.Ban_list.objects.exclude(cname='Python 2期') # print(c1[5].cname)
return render(request, 'class_list.html', {'class_list':class_list}) # ORM 增加数据
def add_class_list(request):
if request.method == 'POST':
c_name = request.POST.get("class_name")
first_day = request.POST.get("first_day1")
models.Ban_list.objects.create(cname=c_name,first_day=first_day) return redirect(reverse('app0001urls:classlist')) #通过别名返回list
# return redirect('/app0001/class_list/ ') #通过真实网址返回list
return render(request, "add_class_list.html")
#
# # ORM 删除数据
def delete_class_list(request):
d_id = request.GET.get('class_id')
models.Ban_list.objects.filter(id=d_id).delete()
# 如果没有页面只能去跳转
# return redirect('/app0001/class_list/')
return redirect(reverse('app0001urls:classlist'))
# # 更改数据
def edit_class_list(request,arg):
# 这里是通过分组取值的方法得到arg,点击编辑的时候生成url 和id的值 id的值就是arg
if request.method == 'POST':
e_id = request.POST.get("class_id")
e_name1 = request.POST.get('class_name')
first1_day = request.POST.get('first_day')
models.Ban_list.objects.filter(id=e_id).update(cname=e_name1,first_day=first1_day)
return redirect(reverse('app0001urls:classlist'))
# 通过编辑的链接取值arg e_name = models.Ban_list.objects.get(id=arg)
return render(request,'edit_class_list.html',{'e_name1':e_name}) # e_id = request.GET.get('class_id') #这里是通过编辑的id 通过的是get 取值 # if request.method == 'POST':
# # e_id = request.POST.get('class_id') 这里不能取值
# # 只有在form 表单里面才能进行post 取值 别的地方就不能取值
# e_name = request.POST.get("class_name")
# models.Ban_list.objects.filter(id=e_id).update(cname=e_name)
# # return redirect('/app0001/class_list/')
# return redirect(reverse('app0001urls:classlist'))
#
# # e_name= models.Ban_list.objects.get(id=e_id) #get 取一条是一个对象
# e_name1 = models.Ban_list.objects.filter(id=e_id) #filter 取一条是一个表 必须加索引
# e_name1 = e_name1[0] #此变量对应后边编辑的默认的值
# return render(request, 'edit_class_list.html', {'e_name1':e_name1}) #
# # 建表 添加数据库的页面
def student_list(request):
st_list = models.Student_list.objects.all()
return render(request, 'student_list.html', {'st_list': st_list}) def add_student_list(request):
if request.method == 'POST':
sname1 = request.POST.get('s_name')
cid1 = request.POST.get('class_id')
# 方法一 通过 cid的值操作 注意这cid_id 这个是Student_list 通过外键形成的,cid 是个对象 cid_id 是个数字
# models.Student_list.objects.create(sname=sname1,cid_id=cid1) # 方法二 通过orm 对象 对应的 学生表的cid对象 而不是cid_idd的值数字
object_c = models.Ban_list.objects.get(id=cid1)
models.Student_list.objects.create(sname=sname1, cid=object_c)
return redirect(reverse('app0001urls:studentlist')) class_list = models.Ban_list.objects.all()
return render(request, 'add_student_list.html',{'class_list':class_list}) def delete_student_list(request,sid):
# 通过url分组取值的方法
models.Student_list.objects.filter(id=sid).delete() # 通过get取值的方法
# d_id = request.GET.get('student_id')
# models.Student_list.objects.filter(id=d_id).delete()
return redirect(reverse('app0001urls:studentlist')) # def edit_student_list(request):
# e_id = request.GET.get('student_id')
# if request.method == 'POST':
# e_sname = request.POST.get('s_name')
# e_cid = request.POST.get('c_id')
# models.Student_list.objects.filter(id=e_id).update(sname=e_sname,cid=e_cid)
# return redirect(reverse('app0001urls:studentlist')) # e_id = request.GET.get('student_id')
# e_svalue2 = models.Student_list.objects.filter(id=e_id)
# e_svalue= e_svalue2[0]
# return render(request, 'edit_student_list.html', {'e_svalue1':e_svalue}) # def edit_student_list(request,arg):
# # e1_svalue = models.Student_list.objects.filter(id=arg)
# if request.method == 'POST':
# # 只有在form 表单里面才能进行post 取值 别的地方就不能取值
# e_name = request.POST.get("class_name")
# models.Ban_list.objects.filter(id=e_id).update(cname=e_name)
# # return redirect('/app0001/class_list/')
# return redirect(reverse('app0001urls:classlist'))
#
# e1_svalue= models.Student_list.objects.filter(id=arg)
# e1_svalue= e1_svalue[0]
# return render(request,'edit_student_list.html',{'e_svalue1':e1_svalue})
def edit_student_list(request,sid):
if request.method == 'POST':
sname1 = request.POST.get('s_name')
class1 = request.POST.get('class_name')
# 方法一 通过分组get 得到一个对象不支持链式操作
# student_obj = models.Student_list.objects.get(id=sid)
# student_obj.sname = sname1
# 注意student_obj 是个对象 学生表链表后 cid 是对象 cid_id 是班级的id
# student_obj.cid_id = class1
# student_obj.save()
# 方法二直接filter 取值 后边直接链式操作
models.Student_list.objects.filter(id=sid).update(sname=sname1, cid_id=class1) return redirect(reverse('app0001urls:studentlist'))
# 先通过分组拿到带有值得form 表单取得对象能链式操作
e_svalue1 = models.Student_list.objects.get(id=sid)
# 取得班级的列表
class_list = models.Ban_list.objects.all()
return render(request,'edit_student_list.html', {'class_list': class_list,'e_svalue1': e_svalue1}) def teacher_list(request): teacher_list = models.Teacher.objects.all()
# cid代表进入一张表 并没有拿取对象
return render(request,'teacher_list.html',{'class_list':class_list,'teacher_list':teacher_list}) def add_teacher_list(request):
if request.method == 'POST':
teacher_name =request.POST.get('teacher_name')
# 通过取得select name 班级的多个id值 的name??????
class_ids =request.POST.getlist('class_id')
# 第一种数据库直接添加 去数据库插入一条信息 老师这个对象 数据库
print(class_ids)
# teacher_obj = models.Teacher.objects.create(tname=teacher_name)
# # 这个老师对象的授课班级表添加id 因为是列表需要打算添加
# teacher_obj.cid.add(*class_ids)
# print(teacher_obj.cid) # 第二中表里添加对象 是之通过条件id增加 注意单个id是可以直接等于 多个的话下划线id__in
teacher_obj = models.Teacher.objects.create(tname=teacher_name)
class_objs = models.Ban_list.objects.filter(id__in=class_ids)
teacher_obj.cid.add(*class_objs) return redirect(reverse('app0001urls:teacherlist'))
class_list = models.Ban_list.objects.all()
return render(request,'add_teacher_list.html',{'class_list':class_list}) def delete_teacher_list(request,tid):
models.Teacher.objects.filter(id=tid).delete()
return redirect(reverse('app0001urls:teacherlist')) def edit_teacher_list(request,tid):
teacher_obj = models.Teacher.objects.get(id=tid)
if request.method == 'POST':
t_name=request.POST.get('teacher_name')
class_ids=request.POST.getlist('class_id')
# 注意这个要保存
teacher_obj.tname=t_name
teacher_obj.save()
teacher_obj.cid.set(class_ids)
return redirect(reverse('app0001urls:teacherlist'))
class_list = models.Ban_list.objects.all()
teacher_id = models.Teacher.objects.get(id=tid)
return render(request,'edit_teacher_list.html',{'class_list':class_list,'teacher_id':teacher_id})

orm view视图 练习增删改查