Django(4)--mysql操作
路由优化配置
- 拆分为多个应用。在app中创建自己的urls
- urlpatterns路由规则列表
- 在根urls中进行子路由的包含
- 子路由
- 根路由规则+子路由规则
djangoadmin startapp app02
- settings.py 注册新项目
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01',
'app02'
]
- app02创建urls.py
from django.conf.urls import url
from app02 import views
urlpatterns = [
url(r'^index/',views.index)
]
- app02/views.py
def index(request):
return HttpResponse('app02 index')
- bookmanager/urls.py
from django.conf.urls import url,include
from django.contrib import admin
#Include语法,来将单独的页面包含到当前模板页面中,路由转发
url(r'^app02/',include('app02.urls'))
django--MySQL
- models 使用了ORM技术
- object relational Mapping 对象关系映射
- 将业务逻辑进行了一个解耦合
- object.save()
- object.delete()
- 关系型数据库
- DDL
- 通过models定义实现,数据表的定义
- 数据操作
- 增删改查
- 存储
- save()
- 查询
- 查所有 objects.all()
- 查单个 objects.get(pk=2)
- 更新
- 基于查询的
- 查好的对象,修改属性,然后save() #基于主键,主键存在就是更新,主键不存在就是创建
- 删除
- 基于查询的
- 调用delete()
- models.py
from django.db import models
class Student(models.Model):#继承Django的models
s_name = models.CharField(max_length=16)
s_age = models.IntegerField(default=1) #default=1默认值
- python命令,将模块刷到数据库
#生成迁移文件
E:\python_data\py27\bookmanager>python manage.py makemigrations
Migrations for 'app01':
app01\migrations\0003_auto_20191121_1645.py
- Create model Student
- Delete model test
#迁移
E:\python_data\py27\bookmanager>python manage.py migrate
Operations to perform:
Apply all migrations: admin, app01, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
....
- app01/urls.py
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^index/',views.index),
url(r'addstudent/',views.add_student)
]
- app01/views.py
from django.shortcuts import render,HttpResponse,redirect
from app01 import models
from app01.models import Student
def add_student(request):
student = Student()
student.s_name='jrrey'
student.save()
return HttpResponse('Add successfully')
-
到数据库刷新查看,可以看见学生已经添加
-
生成新的随机人员
def add_student(request):
student = Student()
student.s_name= 'jerry%d' % random.randrange(100)
student.save()
return HttpResponse('add successfully %s' % student.s_name)
访问 http://127.0.0.1:8000/app01/addstudent/
templates模板展示
- templates两种配置
- 第一种在app01中进行模板配置,app01/templatesm目录
- 如果想让代码自动提示,将文件夹标记为模板文件夹
- 在项目目录中创建模板配置(开发中使用,便于模板继承)
- 在项目中创建templates并标记
- 需要在settings中进行注册
- bookmanager\templates\student_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>student_list</title>
</head>
<body>
<h2>hello</h2>
<h3>{{ hobby }}</h3>
</body>
</html>
展示学生
- 展示学生列表1
app01/urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
#出版社的展示
# url(r'^publishare_list/',views.publishare_list)
# url()
url(r'^login/',views.login),
url(r'index/',views.index),
url(r'addstudent/',views.add_student),
url(r'getstudent/',views.get_student),
]
- app01/views.py
def get_student(request):
students = Student.objects.all() #orm为提供学生操作的一个入口
for student in students:
print(student.s_name)
return HttpResponse('student list')
- 展示学生列表2
def get_student(request):
students = Student.objects.all() #orm为提供学生操作的一个入口
for student in students:
print(student.s_name)
context = {
"hobby":"play games",
"eat":"meat" #如果没在HTML中定义就不会刷出来
} #往模板中传的数据,是个字典
return render(request,'student_list.html',context=context)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>student_list</title>
</head>
<body>
<h2>hello</h2>
<h3>{{ hobby }}</h3>
<h3>{{ eat }}</h3>
</body>
</html>
def get_student(request):
students = Student.objects.all() #orm为提供学生操作的一个入口
for student in students:
print(student.s_name)
context = {
"hobby":"play games",
"eat":"meat", #如果没在HTML中定义就不会刷出来
"students":students
} #往模板中传的数据,是个字典
return render(request,'student_list.html',context=context)
<h1>student list</h1>
<hr>
<ul>
{% for student in students %}
<li>{{ student.s_name }}</li>
{% endfor %}
</ul>
</body>
</html>
修改学生名字
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'addstudent/',views.add_student),
url(r'getstudent/',views.get_student),
url(r'updatestudent/',views.update_student),
]
def update_student(request):
student = Student.objects.get(pk=2) #get获取单个对象,跟个条件pk等于2,pk=2 就是primary主键=2
student.s_name = 'jack'
student.save()
return HttpResponse('student update successfully')
删除学生
def delete_student(request):
student = Student.objects.get(pk=3)
student.delete()
return HttpResponse('student delete successfully')
mysql
- 原始表迁移到新数据库
python manage.py migrate
- 连接 mysqlclient
- python2,3都能直接使用
- 致命缺点
- 对mysql安装有要求,必须指定位置存在配置文件
- python-mysql
- python2支持很好
- python3 不支持
- pymysql
- python2,3都支持
- 可以伪装成前两个库
pip install pymysql -i源
- bookmanager\bookmanager_init_.py #程序最先调用,放驱动
import pymysql
- 测试,增加学生看看能不能刷到数据库
http://127.0.0.1:8000/app01/addstudent/
- 加载模板、渲染模板,好处是支持模板语言
- views.py
from django.shortcuts import render,redirect,HttpResponse
from django.template import loader
def three_index(request):
threeindex = loader.get_template('three.html') #加载
ret = threeindex.render() #渲染成字符串
print(ret)
return HttpResponse(ret)
def three_index(request):
threeindex = loader.get_template('three.html')
context = {
"student_name":"Sunck",
}
ret = threeindex.render(context=context)
print(ret)
return HttpResponse(ret)
python manage.py shell
- (django的shell,一般用于调试)
- 集成了python环境的shell终端
- 通常在终端中做一些调试工作
E:\py27\Django_project\bookmanager>python manage.py shell
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from app01.models import Student
>>> students = Student.objects.all()
>>> for student in students:
... print (student.s_name)
##创建学生
>>> student = Student()
>>> student.s_name = 'Sunck'
>>> student.save()
如何看待bug
- 看日志
- 先看第一条
- 再看最后一条
- 梳理思路
- 程序在哪一个位置和预期出现偏差
表关系
- 1对1 (外键约束)
- 1对多(外键)
- 多对多(额外产生关系表)
级联
- app02/models.py(新类)
class Grade(models.Model):
g_name = models.CharField(max_length=32)
class Student(models.Model):
s_name = models.CharField(max_length=16)
s_grade = models.ForeignKey(Grade,on_delete=models.CASCADE,) #外键到班级
python manage.py makemigrations
python manage.py migrate
- 报错
E:\py27\Django_project\bookmanager>python manage.py makemigrations app02
Traceback (most recent call last):
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "E:\软件\python3\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
utility.execute()
File "E:\软件\python3\lib\site-packages\django\core\management\__init__.py", line 357, in execute
django.setup()
File "E:\软件\python3\lib\site-packages\django\__init__.py", line 24, in setup
apps.populate(settings.INSTALLED_APPS)
File "E:\软件\python3\lib\site-packages\django\apps\registry.py", line 114, in populate
app_config.import_models()
File "E:\软件\python3\lib\site-packages\django\apps\config.py", line 211, in import_models
self.models_module = import_module(models_module_name)
File "E:\软件\python3\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "E:\py27\Django_project\bookmanager\app02\models.py", line 7, in <module>
class Student(models.Model):
File "E:\py27\Django_project\bookmanager\app02\models.py", line 9, in Student
s_grade = models.ForeignKey(Grade)
TypeError: __init__() missing 1 required positional argument: 'on_delete'
原因:
在django2.0后,定义外键和一对一关系的时候需要加on_delete选项,此参数为了避免两个表里的数据不一致问题,不然会报错:
TypeError: __init__() missing 1 required positional argument: 'on_delete'
- 添加班级 app02_grade
+----+-------------+
| id | g_name |
+----+-------------+
| 1 | GP-python-1 |
| 2 | python1887 |
| 3 | python1888 |
| 4 | python1809 |
+----+-------------+
- 添加学生 app02_student
+----+--------+------------+
| id | s_name | s_grade_id |
+----+--------+------------+
| 1 | Sunck | 1 |
| 2 | Tom | 1 |
| 3 | Jack | 1 |
| 4 | Rose | 2 |
| 5 | marry | 3 |
+----+--------+------------+
- bookmanager/urls.py
from django.conf.urls import url,include
from django.contrib import admin
from app01 import views
from app02 import views
urlpatterns = [
url('admin/', admin.site.urls),
# url('login/',views.login),
url('app01/',include('app01.urls')),
url('app02/',include('app02.urls'))
]
- app02/urls.py
from django.conf.urls import url
from app02 import views
urlpatterns = [
# url(r'threeindex/',views.three_index),
url(r'getgrade/',views.get_grate),
url(r'getstudents/',views.get_students),
]
- app02/views.py
from django.shortcuts import render,HttpResponse,redirect
from app02.models import Student
from app02 import models
from app02.models import Grade
# Create your views here.
def get_grate(request):
student = Student.objects.get(pk=1)
grate = student.s_grade
return HttpResponse("Grate %s"%grate.g_name)
# 查询时先查的student,通过student调出grate,这就是简单的数据级联
def get_students(request):
grate = Grade.objects.get(pk=1)
students = grate.student_set.all()
context={
"students":students
}
return render(request,'student_app02_list.html',context=context)
- app02/temlates/student_app02_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>student_list</title>
</head>
<body>
<h3>student list</h3>
<ul>
{% for student in students %}
<li>{{ student.s_name }}</li>
{% endfor %}
</ul>
</body>
</html>