Django数据库的增删查改

模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from django.db import models


class Student(models.Model):
name = models.CharField(max_length=10, unique=True)
age = models.IntegerField(default=18)
gender = models.BooleanField(default=1)

# auto_now_add: 创建数据时,默认create_time字段为当前时间
create_time = models.DateTimeField(auto_now_add=True, null=True)
# auto_now:修改时间,每次update学生信息时,修改该字段的时间为当前时间
operate_time = models.DateTimeField(auto_now=True, null=True)
yuwen = models.DecimalField(max_digits=3, decimal_places=1, null=True)
shuxue = models.DecimalField(max_digits=3, decimal_places=1, null=True)

class Meta:
# 指定student模型映射到数据库中对应的表名
db_table = 'student'

class StuInfo(models.Model):
phone = models.CharField(max_length=11)
address = models.CharField(max_length=100)
# OneToOneField 等价于 ForeignKey,且约束unique=True
stu = models.OneToOneField(Student)

class Meta:
db_table = 'stu_info'

视图页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
from django.db.models import Avg, Count, Sum, Max, Min, Q, F
from django.shortcuts import render
from django.http import HttpResponse
# 引入学生student模型
from app.models import Student, StuInfo


def add_stu(request):
# 像数据库中的student表中插入数据
# 第一种方式进行创建:save()
# stu = Student()
# stu.name = '小明'
# 向数据库中插入一条数据
# stu.save()

# 第二种方式
Student.objects.create(name='莫幺儿', age=19)
return HttpResponse('创建成功')


def del_stu(request):
# 实现删除
# sql: del from student where name='大锤'
# 1.查询name=‘大锤’的信息
# Student.objects.filter(name='大锤').delete()
stus = Student.objects.filter(name='大锤')
stus.delete()
return HttpResponse('删除成功')


def up_stu(request):
# 实现更新
# 第一种方式
# stus= Student.objects.filter(name='莫幺儿')
# 获取莫幺儿对象
# stu = stus[0]
# stu = Student.objects.filter(name='小明').first()
# stu.name = '狗屎'
# stu.save()

# 第二种方式
Student.objects.filter(name='胡歌').update(name='莫宇', age=25)
return HttpResponse('更新成功')


def sel_stu(request):
# 查询
# 查询年龄等于18的学生信息
# first(): 获取结果中的第一个
# last(): 获取结果中的最后一个
stus = Student.objects.filter(age=18)

# 查询所有学生
stus = Student.objects.all()

# 查询name=xxx 的学生信息
# git(): 获取唯一的满足条件对象,且查询的条件必须存在
# 如果查询条件不存在,则报错
# 如果查询的结果大于一个,则报错
stu = Student.objects.get(name='德邦')

# 获取不叫小明的学生信息
stus = Student.objects.exclude(name='小明')

# 查询年龄十八且性别为女的学生信息
stus = Student.objects.filter(age=18).filter(gender=0)
stus = Student.objects.filter(age=18, gender=0)

# 排序order_by
# 降序 -id 在sql中是id desc
# 升序 id,在sql中 id asc
stus = Student.objects.all().order_by('-id')

# 获取对象的值
stus_value = Student.objects.all().values()

# 判断name= 妲己 的学生存不存在,存在返回True, 不存在返回False

stu = Student.objects.filter(name='妲己').exists()

# 查询姓名中包含‘小’的学生信息,contains
# contains : 大小写敏感
# icontains: 大小写不敏感
# 类似于like '%小%'
stu = Student.objects.filter(name__contains='小')

# 类似于like '%小'
stus = Student.objects.filter(name__endswith='小')

# 类似于like '小 %'
stus = Student.objects.filter(name__startswith='小')

# sql: select * from xxx where id in (1,2,3)
stus = Student.objects.filter(id__in=[1, 2, 3])

# pk代表主键
stus = Student.objects.filter(pk__in=[1, 2, 3])

# 大于: __gt__、大于等于: __gte__
# 小于: __lt__、小于等于:__lte__
stus = Student.objects.filter(age__lt=19)

# 查询平均年龄
stus = Student.objects.all()
ages = 0
for stu in stus:
ages += stu.age
avg_age=ages / len(stus)
print(avg_age)

# 聚合aggregate
avg_age = Student.objects.all().aggregate(Avg('age'))
print(avg_age)

# sql:select count(age), sum(age), max(age), min(age) from student;
sum_age = Student.objects.all().aggregate(Sum('age'))
count_age = Student.objects.all().aggregate(Count('age'))
max_age = Student.objects.all().aggregate(Max('age'))
min_age = Student.objects.all().aggregate(Min('age'))
print(sum_age, count_age, max_age, min_age)

# 或者条件、非条件、并且条件
# 查询age=18 并且 gender=1的学生信息
# Q()
# 导入包:from django.db.models import Q
stus = Student.objects.filter(Q(age=18), Q(gender=1))

stus = Student.objects.filter(Q(age=18) & Q(gender=1))
# 查询age=18 或者 gender=1的学生信息
stus = Student.objects.filter(Q(age=18) | Q(gender=1))
# 查询满足age!=18 或者gender=1的条件
stus = Student.objects.filter(~Q(age=18) | Q(gender=1))

# 查询语文成绩比数学成绩好的学生信息
# F()
stus = Student.objects.filter(yuwen__gt=F('shuxue'))

# 查询语文成绩比数学成绩高十分的学生信息
stus = Student.objects.filter(yuwen__gt=F('shuxue') + 10)


# 获取学生的姓名
stu_names = [stu.name for stu in stus]

return HttpResponse(stu_names)


def add_stu_info(request):

# StuInfo.objects.create(phone='13681927364', address='四川省成都市', stu_id=6)

s_info = StuInfo()
s_info.phone = '15451685412'
s_info.address = '天府新区'
# s_info.stu_id = 1
s_info.stu = Student.objects.get(pk=5)
s_info.save()

return HttpResponse('创建拓展成功')


def sel_info_by_stu(request):
# 通过学生信息查拓展表信息
# 查询小花的电话号码
# sql: select stu_info.phone from student,stu_info
# where student.id=stu_info.stu_id

# sql2
# select phone from stu_info,(select id from student) as a
# where stu_info.stu_id=a.id

stu = Student.objects.filter(name='小花').first()
# 第一种方法
# stu_info = StuInfo.objects.filter(stu_id=stu.id).first()
stu_info = StuInfo.objects.filter(stu=stu).first()
phone = stu_info.phone

# 第二种反向查询
stu_info = stu.stuinfo
phone = stu_info.phone
return HttpResponse(phone)


def sel_stu_by_info(request):
# 查询phone=13681927364的学生信息
stu_info = StuInfo.objects.get(phone='13681927364')
stu = stu_info.stu
return HttpResponse('通过拓展表查询学生信息')

1.模型类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    一对一:OneToOneField
一对多:Foreignkey
多对多:ManyToManyFiled

class Student:
# OneToOneField定义在任何一方都可以
stu_info = modles.OneToOneField(Student)

# Foreignkey定义在多的一方
g = modles.Foreignkey(Grade)

# ManyToManyFiled定义在任何一方都可以
c = modles.ManyToManyFiled(Course)

class StuInfo:
id = AutoField()
class Grade:
id = AutoField()
class Course:
id = AutoField()

已知学生对象stu:
- 查询班级:stu.g
- 查询拓展表:stu.stu_info
- 查询课程:stu.c

已知拓展表stu_info对象:
- 查询学生:stu_info.student

已知班级对象grade:
- 查询学生:grade.student_set

已知课程对象course:
- 查询学生:course.student_set

一对一:知道一,查询一,对象点属性字段/对象点查询对象的小写
一对多:知道多,查询一,对象点查询对象的小写_set
多对多:分解成一对多,知道多,查询一

2.模板

index 继承 base_main, base_main 继承 base; 在base中,是一个完整的html结构,并挖坑,在base_main中,是一些通用的样式,在index中是每个页面中自己的内容

base中的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
{% block title %}
{% endblock %}
</title>
</head>
<body>
{% block content}
{% endblock %}
</body>
</html>

base_main中的内容

1
2
3
4
5
6
7
8
9
{% extends 'base.html' %}


{% block title %}
{% endblock %}


{% block content %}
{% endblock %}

index页面或者其他页面的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{% extends 'base.main.html' %}


{% block title %}
登录
{% endblock %}


{% block content %}
<form action="" method="post">
<p>账号:<input type="text" name="username"></p>
<p>密码:<input type="password" name="password"></p>
<p><input type="submit" value="提交"></p>
</form>
{% endblock %}

  • 解析标签:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    {% 标签 %}
    标签有for、if、comment、static、ifequal、block、extends
    {% end标签 %}

    example:
    # 改变编号1的颜色
    <td {% if forloop.counter == 1 %}
    style="color:red;"
    {% endif %}>
    {{ stu.name }}
    </td>
    # 改变编号1的字体大小
    <td {% ifequal forloop.counter 1 %}
    style="font-size:30px;"
    {% endifequal %}>
    {{ stu.age }}
    </td>
  • 注释:

    1
    2
    3
    4
    5
    6
    7
    8
    <!--注解一:在检查源代码的时候能看到,解析的时候也会解析,如果这个注解有错,访问的时候也会出现问题-->

    {# 注解二:{% for 标签用于循环 %} {% endfor 结束标签 %}:检查源代码的时候看不到,出现错误也不会影响用户访问,推荐使用 #}

    {% comment %}
    <P>我是注解三</P>
    检查源代码的时候看不到,出现错误也不会影响用户访问,可以使用
    {% endcomment %}
  • 解析变量:

  • 1
    2
    3
    4
    def index(request):
    # 变量stus,通过index.html解析students的值stus
    stus = Student.objects.all()
    return render(request, 'index.html', {'students': stus})
  • 循环:

    • forloop.counter:从1正序编号
    • forloop.counter0:从0正序编号
    • forloop.revcounter:倒序编号
    • forloop.first:取到第一个
    • forloop.last:取到最后一个
  • 继承:

    • 通用的css、js以及其它的内容写在base_main中,index继承其中的内容
      1
      2
      3
      {% block xxx %}
      {{ block.super }}
      {% endblock %}
  • 静态加载:

    • STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
  • CSS

    • 第一种方式:

      1
      2
      3
      {% block css %}
      <link href="/static/css/index.css">
      {% endblock %}
    • 第二种方式:

      1
      2
      3
      4
      {% block css %}
      {% load static %}
      <link rel="stylesheet" href="{% static 'css/index.css' %}">
      {% endblock %}
  • JS

    • 在父模板中挖JS坑,在子模板中直接继承,不用填坑
    • 不仅要继承JS,还要引入自己的JS模板
      1
      2
      3
      4
      {% block js %}
      {{ block.super }}
      <script src="my.js"></script>
      {% endblock %}