s14_06_Model_基础
model操作基础
- Model
# django为使用一种新的方式,
# 即:关系对象映射(Object Relational Mapping,简称ORM)。
# django中遵循 Code Frist 的原则,
# 即:根据代码中定义的类来自动生成数据库表。
# db first & code first
# 根据类自动创建数据库表
# 根据类对数据库表中的数据进行各种操作
- 基本操作
a. 先写类
# app下的models.py
from django.db import models
# app01_userinfo
class UserInfo(models.Model):
# 隐含id列,自增,主键
# 用户名列,字符串类型,指定长度
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
b. 注册APP
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01',
]
c. 执行命令
# 先注册app
根据类自动创建数据库表
python manage.py makemigrations
python manage.py migrate
d. 其他
- Django默认使用MySQLdb模块链接MySQL
- 修改为pymysql,在project同名文件夹下__init__文件添加代码:
import pymysql
pymysql.install_as_MySQLdb()
- 根据数据库,配置参数:
mysql配置如下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'dbname', # 手动创建数据库
'USER': 'root',
'PASSWORD': 'xxx',
'HOST': '',
'PORT': '',
}
}
- pycharm数据库驱动
C:\Users\jacka\.PyCharm2019.2\config\jdbc-drivers
- 使用navicat链接sqlite
- 右击复制copy path
- nivacat:新建连接- 数据库文件
- views.py
from app01 import models
- admin.py
from django.contrib import admin
from app01 import models
# Register your models here.
admin.site.register(models.UserInfo)
创建 Django 用户:python manage.py createsuperuser
# 一对多/一对一/多对多
一对一:
外键唯一约束。
一对多:
def func():
return 5
class UserType(models.Model):
name = models.CharField(max_length=32)
class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
ForiegnKey(to="UserType",to_field='id',on_delete=models.SET(func))
# delete from user where id=1
# delete from UserType where id=1 # 报错
# UserType.objects.filter(id=1).delete()
# 新版本关联数据默认都删除
# 正向查找
# v = User.objects.all()
# for item in v:
# item.user
# item.pwd
# item.ut.name
# User.objects.all().values('user','ut__name')
# 反向查找
# v= UserType.objects.all()
# for item in v:
# item.name
# item.id
# item.user_set.all()
# related_name='b' ==> item.b.all()
# related_query_name='a' ==> item.a_set.all()
# UserType.objects.all().values('name','user__pwd')
- 多对多:
a. django创建第三张表
m2m.remove
m2m.add
m2m.set
m2m.clear
m2m.filter()
b. 自定义第三张表(无m2m字段)
自己链表查询
c. 自定义第三张表(有m2m字段)
# 通过m2m字段查操作
# 通过m2m字段 clear
- QuerySet中的方法:
- 返回QuerySet类型(select_related,prefetch_related)
select_related
users = models.User.objects.all().select_related('ut')
for row in users:
print(row.user,row.pwd,row.ut_id)
print(row.ut.name)
print(row.tu.name) # 再发起一次SQL请求
prefetch_related
users = models.User.objects.filter(id__gt=30).prefetch_related('ut','tu')
# select * from users where id > 30
# 获取上一步骤中所有的ut_id=[1,2]
# select * from user_type where id in [1,2]
# select * from user_type where id in [1,2]
for row in users:
print(row.user,row.pwd,row.ut_id)
print(row.ut.name)
- 数据验证(弱)
full_clean进行验证
- 每个字段的正则
- clean钩子
class UserInfo(models.Model):
name=models.CharField(max_length=32)
email = models.EmailField()
# 预留的方法
def clean(self):
from django.core.exceptions import ValidationError
c = UserInfo.objects.filter(name=self.name).count()
if c:
# 主动报错
raise ValidationError(message='用户名已经存在',code='i1')
- 操作表
- 增
models.User.objects.create(name='qianxiaohu',age=18)
dic = {'name': 'xx', 'age': 19}
models.User.objects.create(**dic)
obj = models.User(name='qianxiaohu',age=18) # 也可以传字典
obj.save()
- 删
models.User.objects.filter(id=1).delete()
- 改
models.User.objects.filter(id__gt=1).update(name='alex',age=84)
dic = {'name': 'xx', 'age': 19}
models.User.objects.filter(id__gt=1).update(**dic)
- 查
models.User.objects.all()
models.User.objects.filter(id=1,name='root')
models.User.objects.filter(id__gt=1,name='root')
models.User.objects.filter(id__lt=1)
models.User.objects.filter(id__gte=1)
models.User.objects.filter(id__lte=1)
models.User.objects.filter(id=1,name='root')
dic = {'name': 'xx', 'age__gt': 19}
models.User.objects.filter(**dic)
- 查2
v1 = models.Business.objects.all()
# QuerySet ,内部元素都是对象
v2 = models.Business.objects.all().values('id','caption')
# QuerySet ,内部元素都是字典
v3 = models.Business.objects.all().values_list('id','caption')
# QuerySet ,内部元素都是元组
models.Business.objects.get(id=1)
# 获取到的一个对象,如果不存在就报错
models.Business.objects.filter(id=1).first()
# 对象或者None
外键:
v = models.Host.objects.filter(nid__gt=0)
v[0].b.caption ----> 通过.进行跨表
v1 = models.Host.objects.filter(nid__gt=0)
# for row in v1:
# print(row.nid,row.hostname,row.ip,row.port,row.b_id,row.b.caption,row.b.code,row.b.id,sep='\t')
v2 = models.Host.objects.filter(nid__gt=0).values('nid','hostname','b_id','b__caption')
# models.Host.objects.后面跨表用双下划线: "__" ,为普通字符串,取值时为对象
# print(v2)
# QuerySet[{内部为字典},{字典}]
# for row in v2:
# print(row['nid'],row['hostname'],row['b_id'],row['b__caption'])
v3 = models.Host.objects.filter(nid__gt=0).values_list('nid','hostname','b_id','b__caption')
class UserType(models.Model):
caption = models.CharField(max_length=32)
# id caption
class User(models.Model):
age = models.IntergerFiled()
name = models.CharField(max_length=10)#字符长度
# user_type_id = models.IntergerFiled() # 约束
user_type = models.ForeignKey("UserType",to_field='id') # 约束
# name age user_type_id
# models.tb.object.create(name='root', user_group_id=1)
# userlist = models.tb.object.all()
for row in userlist:
row.id
row.user_group_id
row.user_group.caption
# user = User.objects.get(id=1) # 得到单个对象
- 序号相关
{% for row in v1 %}
<td>{{ forloop.counter}}</td> # 序号从1开始
<td>{{ forloop.counter0}}</td> # 序号从0开始
<td>{{ forloop.revcounter}}</td> # 倒序从1开始
<td>{{ forloop.revcounter0}}</td> # 倒序从0开始
<td>{{ forloop.last}}</td> # 是否最后一个
<td>{{ forloop.firs}}</td> # 是否第一个
<td>{{ forloop.parentloop}}</td> # 如嵌套,显示父循环次数
{%endfor%}
- 多对多:
- 自定义关系表
class Host(models.Model):
nid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32,db_index=True)
ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
port = models.IntegerField()
b = models.ForeignKey(to="Business", to_field='id')
class Application(models.Model):
name = models.CharField(max_length=32)
class HostToApp(models.Model):
hobj = models.ForeignKey(to='Host',to_field='nid')
aobj = models.ForeignKey(to='Application',to_field='id')
# app01_hosttoapp 表 id,aobj_id,hobj_id
# HostToApp.objects.create(hobj_id=1,aobj_id=2)
- 自动创建关系表
class Host(models.Model):
nid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32,db_index=True)
ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
port = models.IntegerField()
b = models.ForeignKey(to="Business", to_field='id')
class Application(models.Model):
name = models.CharField(max_length=32)
r = models.ManyToManyField("Host")
# app01.application_r 表 id,application_id,host_id
# 无法直接对第三张表进行操作
obj = Application.objects.get(id=1)
obj.name
- 第三张表操作
obj.r.add(1)
obj.r.add(2)
obj.r.add(2,3,4)
obj.r.add(*[1,2,3,4])
obj.r.remove(1)
obj.r.remove(2,4)
obj.r.remove(*[1,2,3])
obj.r.clear()
obj.r.set([3,5,7])
# objects后的都可以使用
obj.r.all()
# 所有相关的主机对象“列表” QuerySet
obj.r.all()