**
python学习使用Django框架连接mysql数据库的步骤和遇到的一些问题
**
配置数据库:
项目的settings.py文件的77行修改如下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'myproject',
'USER': 'root',
'PASSWORD': 'root',
'HOST': '127.0.0.1',
'PORT': '3306'
}
}
先在models.py文件中创建对应数据库的表,直接上代码吧:
"""
创建学生信息表模型
"""
from django.db import models
"""
该类是用来生成数据库的 必须要继承models.Model
"""
class Student(models.Model):
"""
创建如下几个表的字段
"""
# 学号 primary_key=True: 该字段为主键
studentNum = models.CharField('学号', primary_key=True, max_length=15)
# 姓名 字符串 最大长度20
name = models.CharField('姓名', max_length=20)
# 年龄 整数 null=False, 表示该字段不能为空
age = models.IntegerField('年龄', null=False)
# 性别 布尔类型 默认True: 男生 False:女生
sex = models.BooleanField('性别', default=True)
# 手机 unique=True 该字段唯一
phone = models.CharField('手机', unique=True, max_length=15)
# 创建时间 auto_now_add:只有在新增的时候才会生效
createTime = models.DateTimeField(auto_now_add=True)
# 修改时间 auto_now: 添加和修改都会改变时间
modifyTime = models.DateTimeField(auto_now=True)
# 指定表名 不指定默认APP名字——类名(app_demo_Student)
class Meta:
db_table = 'student'
"""
学生社团信息表
"""
class studentUnion(models.Model):
# 自增主键, 这里不能设置default属性,负责执行save的时候就不会新增而是修改元素
id = models.IntegerField(primary_key=True)
# 社团名称
unionName = models.CharField('社团名称', max_length=20,null=False)
# 社团人数
unionNum = models.IntegerField('人数', default=0,null=True)
# 社团负责人 关联Student的主键 即studentNum学号 一对一的关系,on__delete 属性在django2.0之后为必填属性后面会介绍
unionRoot = models.OneToOneField(Student, on_delete=models.DO_NOTHING,null=False)
class Meta:
db_table = 'student_union'
"""
OneToOneField: 一对一
ForeignKey: 一对多
ManyToManyField: 多对多(没有ondelete 属性)
"""
就是大概创建了两个表,(可根据需要自己创建,字段什么的都可以自己定义,怎么定义问度娘)
需要说的一点就是这个表定义配置好了之后在控制台执行两个命令:
python manage.py makemigrations //先执行这个 ①
python manage.py migrate //再执行这个 ②
第一条命令的作用是生成数据库迁移文件如图:
但是我刚开始学习使用时遇到了问题,在执行的时候一直不成功,shell窗口一直报错,老鼻子劲才找到为啥:出错的地方:
on_delete函数还是方法啥的,一开始写的时候没有赋值,反正就是这个报错导致一直不能生成成功,可以看到
on_delete = model,DO_NOTHING
报错信息没记录,是一直提示on_delete有问题,很明显,我最开始修改的是写成
on_delete = model,DO_NOTHING()
但是还是生成不了文件,报错,最后把括号去掉就对了,直接用model点出来的后面会跟着括号,
具体的这个用法
on_delete=None, # 删除关联表中的数据时,当前表与其关联的field的行为
on_delete=models.CASCADE, # 删除关联数据,与之关联也删除
on_delete=models.DO_NOTHING, # 删除关联数据,什么也不做
on_delete=models.PROTECT, # 删除关联数据,引发错误ProtectedError
# models.ForeignKey('关联表', on_delete=models.SET_NULL, blank=True, null=True)
on_delete=models.SET_NULL, # 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理)
# models.ForeignKey('关联表', on_delete=models.SET_DEFAULT, default='默认值')
on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)
on_delete=models.SET, # 删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
这是其中一个出错的地方,解决完之后就可以执行第二个命令,然后会生成一堆数据表:
其中红框是我们写在models.py文件里面的数据表格,黄框好像是Django框架默认生成的,我也没管,不需要可以删了。
后面如果想修改数据表的属性名什么的,在models.py文件中直接修改好,然后再按顺序执行一遍那两个命令就成,会生成修改记录文件:
最后在说一下我在插入数据时遇到的问题:首先在创建的APP下创建如下文件
代码如下:
"""
数据库对象操作 增删改查
"""
from firstPython.models import Student, studentUnion
class student(object):
def __int__(self):
self
def __init__(self,studentNum,name,age,sex):
self.studentNum = studentNum
self.name = name
self.age = age
self.sex = sex
def test(self):
# 直接创建对象方法
student = Student()
student.name = 'test'
student.age = 26
student.studentNum = 17
student.sex = True
student.phone = 19785412369
# 利用对象的save()方法保存数据库
student.save()
student_union = studentUnion()
student_union.id = 2
student_union.unionName = 'test3'
student_union.save()
# 类的继承
class liming(student):
def __init__(self,name,age,sex,score):
super(liming,self).__init__(name,age,sex)
self.score = score
里面有一个liming的类不用看,可以看到有两个__init__方法,一个带参数,一个不带参数。参数都是刚才models.py里面的数据表的属性名称。
首先说下我为什么会创建两个__init__方法,一开始是只有一个带参数的:
再看views.py文件的代码:
import os
from django.shortcuts import render
# Create your views here.
from django.shortcuts import render
from django.shortcuts import HttpResponse
from firstPython.models import Student
from firstPython import mysqlOpera
from django.shortcuts import redirect
# Create your views here.
USER_LIST = {}
def login(request):
if request.method == 'GET': # 判断请求方式
return render(request, 'login.html')
elif request.method == 'POST':
user = request.POST.get('user') # post请求,单选、输入框获取值
pwd = request.POST.get('pwd')
sex = request.POST.get('sex')
city = request.POST.getlist('city')
file = request.FILES.get('upload')
print(type(file),file)
print(file.chunks)
# 主要得从这里开始 其他的可以不用看
student = Student()
student.studentNum = 16
student.name = '李咩咩'
student.age = 23
student.sex = False
student.phone = 15155208874
student.save()
# 调用测试类对象的方法向数据库插入数据
studentTest = mysqlOpera.student()
studentTest.test()
# 到这里结束 是往数据表中插入数据
# 保存上传的文件到upload目录
upload_path = os.path.join('upload',file.name)
# 打开文件
fw = open(upload_path,'wb')
for line in file.chunks():
fw.write(line)
fw.close()
if user and pwd:
USER_LIST['name'] = user
USER_LIST['pwd'] = pwd
USER_LIST['sex'] = sex
USER_LIST['city'] = city
USER_LIST['file'] = file.name
return render(request, 'success.html', {"user_list": USER_LIST})
else:
return HttpResponse('请求不能为空')
else:
return HttpResponse('请求方式不是get\post') # HttpResponse("字符串")
看一下我中间标记的内容就好,中间我创建了刚才创建的文件的对象,并调用里面的test()方法:
studentTest = mysqlOpera.student()
studentTest.test()
test()方法内容:
这个代码在上面粘贴的代码里可以找到,这个方法就是往数据库里插入数据,但是这样直接调用是报错的如下:
TypeError: __init__() missing 4 required positional arguments: 'studentNum', 'name', 'age', and 'sex'
大概意思是缺少必须的四个参数:
因为__init__方法,然后我就在想这是不是跟Java一样的有参构造跟无参构造,然后我就创建__init__不带参数的方法,发现没有用,在创建对象的时候还是需要传入必要的参数。我也是初学者,这个具体的原因我还没搞明白,
传入参数就好了,但是这个存入数据表的数据还是以test方法中创建的对象传入的值为主要,这个参数数据不会存入数据库。(原因未知)
今天算是连接上了数据库,也成功插入了数据,中间快把度娘搜烂了,搜到的类容还都是一样的(唉)。
开始学习,每天一点!!!!奥利给
–HO