1.ORM操作:
1.创建数据库'db4_16'
2.在settings.py中把django的默认数据库sqlite修改为mysql
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db4_16',
'USER':'root',
'PASSWORD':'123',
'HOST':'localhost',
'PORT':3306
}
}
3.在__init__.py中写入以下代码,把MySQLdb(默认)修改为通过pymysql模块来连接数据库
import pymysql
pymysql.install_as_MySQLdb()
4.在settings里注册app01
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',#注册app01,自动创建,如果需要注册app02,就在下面添加
'app02'
]
5.创建表字段
在app01的models.py里面写入类,创建字段名nid,username,password
注意:nid不写也可以,数据库自动创建id(主键自增)。
from django.db import models
class UserInfo(models.Model):
nid = models.BigAutoField(primary_key=True)
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
6.创建数据表,在Terminal终端输入命令:
python manage.py makemigrations
python manage.py migrate
注意: django 3.0.5 ,pymysql 0.9.3,输入python manage.py makemigrations
出现问题:mysqlclient 1.3.13 or newer is required; you have 0.9.3.
解决办法:
1.cmd安装django2.2:pip install -i https://pypi.mirrors.ustc.edu.cn/simple/ django==2.2
2.创建项目的时候勾选Inherit global site-packages(继承全局的site-packages包)
3.打开路径C:PythonLibsite-packagesdjangodbackendsmysql的base.py,
把第35和36行注释if version < (1, 3, 13):
raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)
4.打开同样路径的operations.py,把146行的decode修改为encode
如果已经使用了django 3.0.5创建了项目,就算后面把版本修改为2.2,还是无法解决问题。
2.#类创建表格,在models中利用类来创建表名,添加和修改表字段,在views中利用类.对象.方法来做增删改查
2.1 models.py创建表字段
from django.db import models
class UserInfo(models.Model):
# nid = models.BigAutoField(primary_key=True)
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
#设置默认值为1。当表格有数据,新添age会有提示,输入2退出,然后设置default=1或者null=True
age = models.IntegerField(default=1)
#设置为空
# age = models.IntegerField(null=True)
#设置外键
ug = models.ForeignKey('UserGroup',null=True,on_delete=None)
class UserGroup(models.Model):
title = models.CharField(max_length=32)
class UserInfo2(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
ut = models.ForeignKey('UserType',null=True,on_delete=None)
class UserType(models.Model):
title = models.CharField(max_length=32)
2.2 views.py表的增删改查
from django.shortcuts import render, HttpResponse
from app01 import models
from django.core.paginator import Paginator
def index(request, a1):
# 增,ug在数据库被更名为ug_id,ug_id等于与之关联的表的id
create = models.UserInfo.objects.create(username='tom', password='111', age=18, ug_id=1)
# 删
delete = models.UserInfo.objects.filter(id=4).delete()
# 改
update = models.UserInfo.objects.filter(id=5).update(username='alex')
# 查全部,结果是列表,列表里的每一个对象就是一行,for循环取值
select_all = models.UserInfo.objects.all()
print(select_all) # [<UserInfo: UserInfo object (5)>, <UserInfo: UserInfo object (6)>]
for row in select_all:
print(row.id, row.username, row.password, row.age, row.ug_id)
# 查一行
select_one = models.UserInfo.objects.filter(id=6)
print(select_one) # [<UserInfo: UserInfo object (6)>]
# 查出id大于1
select1 = models.UserInfo.objects.filter(id__gt=1)
# 查出id小于7
select2 = models.UserInfo.objects.filter(id__lt=7)
return render(request, 'index.html', {'create': create, 'select_all': select_all})
################################连表查询##########################################
#无论正向还是反向查询,在前面的表都能显示出来,而没关联的就显示none,跟mysql的left join一样。
#表1关联表2,表1查询表2属于正向,而表2查询表1属于反向。
def test(request):
models.UserInfo2.objects.create(name='tom',age=18,ut_id=1)
models.UserInfo2.objects.create(name='marry',age=18,ut_id=1)
models.UserInfo2.objects.create(name='alex',age=18,ut_id=2)
models.UserInfo2.objects.create(name='jone',age=18,ut_id=2)
models.UserInfo2.objects.create(name='json',age=18,ut_id=3)
models.UserInfo2.objects.create(name='lily',age=18,ut_id=3)
models.UserType.objects.create(title='普通用户')
models.UserType.objects.create(title='黄金用户')
models.UserType.objects.create(title='白金用户')
#简记:表1关联表2,表1对象.外键.表2属性获取到表2的值,而表2通过表1名小写获取表1的值。
# 连表查询:关联表的属性值 = 本表对象.外键.关联表的属性,例如first.ut.title
first = models.UserInfo2.objects.all().first()#拿到第一个对象,而不是对象列表。
#ut外键关联UserType,是UserType的一行,利用它实现连表查询
print(first.name,first.age,first.ut_id,first.ut.title)#tom 18 1 普通用户
# 反向操作1:获取普通用户都有谁。一个用户只有一个用户类型,而一个用户类型有多个用户。
# 1.先查出普通用户的对象row
row = models.UserType.objects.all().first()
print(row.id,row.title)#1 普通用户
#2.关联表对象 = 本表对象.关联表名小写_set.all()
obj = row.userinfo2_set.all()
for i in obj:
print(i.name)#tom marry
#反向操作2:注意关联表名是小写,属性带双下划线
obj1 = models.UserType.objects.values('id','title','userinfo2')
obj2 = models.UserType.objects.values('id','title','userinfo2__age','userinfo2__name')
# values获取指定值,结果是[dict1,dict2...],注意'ut__title'是连表查询
v = models.UserInfo2.objects.values('name', 'age', 'ut__title')
print(v)#[{},{}...]
for i in v:
print(i['name'], i['age'], i['ut__title'])
# values_list获取指定值,结果是[tup1,tup2...],注意'ut__title'是连表查询
val = models.UserInfo2.objects.values_list('name', 'age', 'ut__title')
print(val)#[(),(),...]
for i in val:
print(i[0], i[1], i[2])
return HttpResponse('...')
3.CBV
3.1 urls.py
urlpatterns = [
url('login/', views.Login.as_view()),#CBV固定写法,必须有.as_view(),Login是类
]
3.2 views.py
# CBV:View中有get和post方法,必须继承
from django.views import View
class Login(View):
# 当通过GET发送数据,就会启动这个get方法
def get(self, request):
return HttpResponse('get')
# 当通过POST发送数据,就会启动这个post方法
def post(self, request):
return HttpResponse('post')