[Python自学] day-19 (2) (Django-ORM)
一、ORM的分类
ORM一般分为两类:
1.DB first:先在DB中创建数据库、表结构,然后自动生成代码中的类。在后续操作中直接在代码中操作相应的类即可。
2.Code first:直接在代码中实现各种类,然后执行,代码自动在DB中创建对应的数据库和表结构。
最常用的是后者,即Code First类型的ORM。例如 [Python自学] day-12 (Mysql、事务、索引、ORM) 中的SQLAlchemy,我们即将要了解的Django ORM也属于Code first。
二、利用ORM创建表
在我们不修改Django数据库配置的情况下,Django默认使用的数据库是sqlite3:
我们暂且使用该默认的数据库。
1.在cmdb APP中的models.py中创建一个类
from django.db import models class UserInfo(models.Model):
# ORM会自动帮我们生成一个id列,是自增的 # 生成cmdb_userinfo表,里面含有username和password两列
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
2.使用命令行在数据库中生成表
python manage.py makemigrations
理论上,会在cmdb/migrations中生成一个临时文件。但是这里并未生成,这是因为cmdb这个APP的models.py并未装载到Django中,所以Django找不到该models.py。
3.配置settings.py(重要)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'cmdb',
]
4.再次执行命令行
D:\pycharm_workspace\secondsite>d:\Dev_apps\Anaconda5.3.0\python.exe manage.py makemigrations
Migrations for 'cmdb':
cmdb\migrations\0001_initial.py
- Create model UserInfo
我们查看cmdb/migrations目录:
然后执行命令:
D:\pycharm_workspace\secondsite>d:\Dev_apps\Anaconda5.3.0\python.exe manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, cmdb, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying cmdb.0001_initial... OK
Applying sessions.0001_initial... OK
我们可以看到,Django除了帮我们执行了cmdb.0001_initial,还执行了一大堆其他的东西,这些东西是Django默认帮我们生成的表,包括sessions等常用的东西。
三、配置使用Mysql数据库
查看settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
可以看到,这里配置使用数据库后端为sqlite3。
我们将其修改为Mysql:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'dbname', # 数据库名,这个django不能帮我们创建,需要我们手工创建
'USER': 'root', # 登录用户名
'PASSWORD': 'xxx', # 登录密码
'HOST': '', # IP
'PORT': '', # port
}
}
修改完settings.py后,执行命令,即可在mysql中创建表:
python manage.py makemigrations
python manage.py migrate
特别注意:(非常重要)
Django连接mysql默认使用的事MySQLdb模块,但是在python3中还没有这个模块。
我们需要在工程目录的__init__.py:
写入以下代码:
import pymysql pymysql.install_as_MySQLdb()
四、查看sqlite3数据库
使用Navicat软件连接sqlite3数据库,查看Django-ORM为我们创建的表。
1.运行Navicat软件:
2.连接sqlite3数据库:
3.查看数据库中的表
我们可以从中找到我们在cmdb/models.py中使用类创建的表,这里叫 cmdb_userinfo。
4.查看cmdb_userinfo表
可以看到,表中有三个列,id列(django自动创建,自增的)、username列和password列。
五、ORM插入数据(基础)
我们写一个orm测试页面。
1.在cmdb/urls.py中添加一个映射关系:
urlpatterns = [
path('admin/', admin.site.urls),
path('login', views.login),
path('home', views.home),
# path('mypage', views.MyPage.as_view()),
path('mypage12376sjhdfjnwjer', views.MyPage.as_view(), name='mypage'),
path('users', views.user_page),
re_path('details-(\d+).html', views.details),
path('orm', views.orm_test),
]
2.在视图函数中使用ORM插入数据:
# 导入cmdb的models模块
from cmdb import models def orm_test(request):
# 在表中插入一条数据
models.UserInfo.objects.create(
username='root',
password=''
)
return HttpResponse('ok')
另外一种方式:
def orm_test(request):
obj = models.UserInfo(username='alex', password='')
obj.save()
return HttpResponse('ok')
第三种方式(第一种的变种,其实就是拆包):
def orm_test(request):
# 在表中插入一条数据
dic = {'username': 'eric', 'password': ''}
models.UserInfo.objects.create(**dic)
return HttpResponse('ok')
3.请求http://127.0.0.1/cmdb/orm
4.查看数据库中的cmdb_userinfo表
我们可以看到,数据已经成功插入表中。
六、ORM查询数据(基础)
1.查询表中所有数据(相当于select * from cmdb_userinfo;):
def orm_test(request):
# 查询数据,返回的result是QuerySet类型,实际上相当于一个列表,每个元素是一个对象,相当于 select * from cmdb_userinfo;
result = models.UserInfo.objects.all()
# 便利result中的每个对象,其中每列对应一个成员属性
for row in result:
print(row.id, row.username, row.password)
return HttpResponse('ok')
2.查询部分列(相当于 select username,password from cmdb_userinfo;):
def orm_test(request):
# result同样是QuerySet,但每个元素变成了字典
result = models.UserInfo.objects.all().values('username','password')
# 遍历result中的每个对象
for row in result:
print(row['username'], row['password'])
return HttpResponse('ok')
当然,我们如果将result通过render函数合并进模板,在模板语言中也要按result的结构来获取数据。
除了使用values()来获取部分列,还可以使用values_list('username','password'):
def orm_test(request):
# result同样是QuerySet,但每个元素变成了元组
result = models.UserInfo.objects.all().values_list('username','password')
# 遍历result中的每个对象
for row in result:
print(row[0], row[1])
return HttpResponse('ok')
3.过滤查询(相当于 select * from cmdb_userinfo where username='alex';):
def orm_test(request):
# 过滤查询,过滤出username='alex'的记录
result = models.UserInfo.objects.filter(username='alex')
# 便利result中的每个对象,其中每列对应一个成员属性
for row in result:
print(row.id, row.username, row.password)
return HttpResponse('ok')
如果是多个过滤条件组成交集(AND),则为:
models.UserInfo.objects.filter(username='alex', password='')
七、ORM删除数据(基础)
def orm_test(request):
# 删除所有数据
models.UserInfo.objects.all().delete()
# 删除过滤数据
models.UserInfo.objects.filter(username='alex').delete() return HttpResponse('ok')
八、ORM更新数据(基础)
1.基本更新操作
def orm_test(request):
# 修改所有条目的password
models.UserInfo.objects.all().update(password='')
# 修改部分条目的password
models.UserInfo.objects.filter(username='alex').update(password='') return HttpResponse('ok')
2.同时更新多个数据
def orm_test(request):
# 修改部分条目的password
models.UserInfo.objects.filter(id=3).update(password='', username='Leo') return HttpResponse('ok')
九、实现基于数据库的用户登录
1.login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="/static/commons.css"/>
<style>
label{
width: 80px;
text-align: right;
display: inline-block;
}
.error_span{
color: red;
}
</style>
</head>
<body class="common">
<form action="/cmdb/login/" method="post">
<p>
<label for="username">用户名:</label>
<input id="username" type="text" name="user"/>
<span class="error_span">{{ user_error }}</span>
</p>
<p>
<label for="password">密码:</label>
<input id="password" type="password" name="pwd"/>
<input type="submit" value="提交"/>
<span class="error_span">{{ pwd_error }}</span>
</p>
</form>
<script src="/static/jquery-1.12.4.js"></script>
</body>
</html>
2.cmdb/urls.py映射关系
urlpatterns = [
path('login/', views.login),
]
3.cmdb/views.py视图函数
def login(request):
if request.method == 'POST':
username = request.POST.get('user', None)
password = request.POST.get('pwd', None) pwd_error_msg = ''
# 从数据库中验证用户名密码是否存在,filter获取的是一个列表,first是取列表的第一个元素,即一条记录或者None
obj = models.UserInfo.objects.filter(username=username, password=password).first()
if obj:
return redirect('http://www.baidu.com')
else:
pwd_error_msg = "账号或密码不正确"
return render(request, 'login.html', {"pwd_error": pwd_error_msg})
4.实现效果
输入账号密码提交给后台,然后从数据库验证,如果正确,则跳转到www.baidu.com,如果不正确则跳转回当前页面,重新输入。
十、ORM修改表结构
修改表结构,直接对app/models.py中的类进行修改就可以了。
修改完后都要执行以下命令:
python manage.py makemigrations
python manage.py migrate
1.修改数据类型(长度)
class UserInfo(models.Model):
# ORM会自动帮我们生成一个id列,是自增的 # 生成UserInfo表,里面含有username和password两列
username = models.CharField(max_length=32)
#password = models.CharField(max_length=64)
password = models.CharField(max_length=80) # 将密码的长度修改为80
如果将长度改短,则如果数据超出长度,会丢失。
2.增加列
class UserInfo(models.Model):
# ORM会自动帮我们生成一个id列,是自增的 username = models.CharField(max_length=32)
#password = models.CharField(max_length=64)
password = models.CharField(max_length=80) # 将密码的长度修改为80
email = models.CharField(max_length=100) # 增加一列email
默认增加的列是不能为空的,所以在执行"python manage.py makemigrations"命令时会弹出提示:
(venv) D:\pycharm_workspace\secondsite>d:\Dev_apps\Anaconda5.3.0\python.exe manage.py makemigrations
You are trying to add a non-nullable field 'email' to userinfo without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
) Provide a one-off default now (will be set on all existing rows with a null value for this column)
) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
>>> "xxx@email.com"
Migrations for 'cmdb':
cmdb\migrations\0002_auto_20191218_1319.py
- Add field email to userinfo
- Alter field password on userinfo
选择1,然后输入默认值。接着再执行"python manage.py migrate"命令。
执行列可以为空:
class UserInfo(models.Model):
# ORM会自动帮我们生成一个id列,是自增的 username = models.CharField(max_length=32)
password = models.CharField(max_length=80)
email = models.CharField(max_length=100, null=True) # 增加一列email,允许为空
使用"null=True"设置列允许为空。
3.删除列
class UserInfo(models.Model):
# ORM会自动帮我们生成一个id列,是自增的 username = models.CharField(max_length=32)
password = models.CharField(max_length=80)
#email = models.CharField(max_length=100, null=True) # 删除email列
注释或删除需要删除的列对应属性。然后重新
十一、ORM字段类型
在mysql数据库中,有字符串、数字、二进制等类型,在Django的ORM中也有对应的字段类型。
前面我们使用了CharField类型:
username = models.CharField(max_length=32)
ORM提供的数据类型:
AutoField(Field)
- int自增列,必须填入参数 primary_key=True BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True 注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models class UserInfo(models.Model):
# 自动创建一个列名为id的且为自增的整数列
username = models.CharField(max_length=) class Group(models.Model):
# 自定义自增列
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=) SmallIntegerField(IntegerField):
- 小整数 - ~ PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 ~
IntegerField(Field)
- 整数列(有符号的) - ~ PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 ~ BigIntegerField(IntegerField):
- 长整型(有符号的) - ~ 自定义无符号整数字段 class UnsignedIntegerField(models.IntegerField):
def db_type(self, connection):
return 'integer UNSIGNED' PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
'AutoField': 'integer AUTO_INCREMENT',
'BigAutoField': 'bigint AUTO_INCREMENT',
'BinaryField': 'longblob',
'BooleanField': 'bool',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'DurationField': 'bigint',
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'IntegerField': 'integer',
'BigIntegerField': 'bigint',
'IPAddressField': 'char(15)',
'GenericIPAddressField': 'char(39)',
'NullBooleanField': 'bool',
'OneToOneField': 'integer',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time',
'UUIDField': 'char(32)', BooleanField(Field)
- 布尔值类型 NullBooleanField(Field):
- 可以为空的布尔值 CharField(Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度 TextField(Field)
- 文本类型 EmailField(CharField):
- 字符串类型,Django Admin以及ModelForm中提供验证机制 IPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制 (过期) GenericIPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
- 参数:
protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, 如果指定为True,则输入::ffff:192.0..1时候,可解析为192.0.2.,开启刺功能,需要protocol="both" URLField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证 URL SlugField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号) CommaSeparatedIntegerField(CharField)
- 字符串类型,格式必须为逗号分割的数字 UUIDField(Field)
- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证 FilePathField(Field)
- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹 FileField(Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage ImageField(FileField)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串) DateTimeField(DateField)
- 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField(DateTimeCheckMixin, Field)
- 日期格式 YYYY-MM-DD TimeField(DateTimeCheckMixin, Field)
- 时间格式 HH:MM[:ss[.uuuuuu]] DurationField(Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型 FloatField(Field)
- 浮点型 DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度 BinaryField(Field)
- 二进制类型
上述提供的字段类型主要分为四类:
- 字符串
- 数字
- 时间
- 二进制
注意:我们可以看到一些URLField、EmailField,看似有语法验证的功能,但实际上就是一个普通的CharField。
为什么要提供这种特殊的字段,是因为Django为我们提供的admin后台管理组件要使用他们,当我们创建这样的字段时,如果使用admin进行数据库后台管理,那么页面上就会进行语法验证(对于数据库还是varchar)。
AutoField:
from django.db import models class UserInfo(models.Model):
# 手工创建自增id列(手工创建了,Django就不会自动创建)
uid = models.AutoField(primary_key=True) # 生成UserInfo表,里面含有username和password两列
username = models.CharField(max_length=32)
password = models.CharField(max_length=80)
使用AutoField可以手工创建自增id列,必须指定为主键。
十二、ORM字段的参数
ORM提供的字段类型,可以使用以下参数:
null 数据库中字段是否可以为空 eg. null=True 允许为空
db_column 数据库中字段的列名 eg. db_column='c_name' 设置列名为c_name
db_tablespace
default 数据库中字段的默认值 eg. default='content' 默认值为content
primary_key 数据库中字段是否为主键 eg. primary_key=True 设置为主键
db_index 数据库中字段是否可以建立索引 eg. db_index=True 建立索引
unique 数据库中字段是否可以建立唯一索引 eg. unique=True 唯一索引
unique_for_date 数据库中字段【日期】部分是否可以建立唯一索引 eg. 2019年1月1日11时11分11秒 只对其中的日期做索引
unique_for_month 数据库中字段【月】部分是否可以建立唯一索引 eg. 只对月份做索引
unique_for_year 数据库中字段【年】部分是否可以建立唯一索引 eg. 只对年份做索引 auto_now 用于时间字段,在更新数据时自动插入当前时间(也包括新插入数据时)
eg.
uptime = models.DateTimeTield(auto_now=True, null=True)
要使该时间更新,不能使用:
obj = models.UserInfo.objects.filter(id=).update(password='')
必须使用:
obj = models.UserInfo.objects.filter(id=).first()
obj.password=""
obj.save() # 此时uptime才会更新 auto_now_add 用于时间字段,在插入数据时自动插入当前时间
eg.
ctime = models.DateTimeTield(auto_now_add=True, null=True) verbose_name Admin中显示的字段名称 eg. verbose_name="用户名" 页面上就不会显示"username",而是显示"用户名"
blank Admin中是否允许用户输入为空 eg. blank=True 页面上不填内容提交时,不会进行内容为空的提示
editable Admin中是否可以编辑 eg. editable=False 页面上相应输入框消失(不可编辑)
help_text Admin中该字段的提示信息 eg. help_text="输入密码" 页面上会在密码输入框下显示"输入密码"提示
choices Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
如:gf = models.IntegerField(choices=[(, '何穗'),(, '大表姐'),],default=) error_messages 自定义错误信息(字典类型),从而定制想要显示的错误信息;
字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
如:{'null': "不能为空.", 'invalid': '格式错误'} validators 自定义错误验证(列表类型),从而定制想要的验证规则
from django.core.validators import RegexValidator
from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
如:
test = models.CharField(
max_length=,
error_messages={
'c1': '优先错信息1',
'c2': '优先错信息2',
'c3': '优先错信息3',
},
validators=[
RegexValidator(regex='root_\d+', message='错误了', code='c1'),
RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'),
EmailValidator(message='又错误了', code='c3'), ]
)
其中有很大一部分是专门用于操作Django admin后台管理页面的。
十三、ORM外键
例如有两个表:用户表和部门表
from django.db import models class GroupInfo(models.Model):
gid = models.AutoField(primary_key=True)
groupname = models.CharField(max_length=32) class UserInfo(models.Model):
# 手工创建自增id列(手工创建了,Django就不会自动创建)
uid = models.AutoField(primary_key=True)
# 添加一个列,使用外键,外键为GroupInfo表中的gid列(该列的值必须是唯一的),如果不写to_field则默认使用主键,默认值为1
group = models.ForeignKey('GroupInfo', to_field='gid', default=1)
# 生成UserInfo表,里面含有username和password两列
username = models.CharField(max_length=32)
password = models.CharField(max_length=80)
特别注意:虽然我们定义外键时使用的变量名叫"group",但Django帮我们在表里生成的实际的列名叫做"group_id"。如下图所示:
当我们查询某个用户信息时,联合UserGroup表一起查询该用户所在group:
def orm_test(request):
# 向UserGroup表中插入一个group (gid=1,groupname='Dev')
models.UserGroup.objects.create(groupname="Dev")
# 向UserInfo表中插入一个user (uid=1,username='Leo',password='123',group_id=1),注意这里要使用真实列名group_id
models.UserInfo.objects.create(username="Leo", password='', group_id=1) # 联合查询UserInfo以及UserGroup
# 获取第一个用户,这里只有一个用户Leo
obj = models.UserInfo.objects.filter(uid=1).first()
# 打印用户的用户名、密码(这些内容都在UserInfo表中)
print(obj.username)
print(obj.password)
# 这里注意,group是外键,指向UserGroup表,所以这里的group属性是一个对象(UserGroup表的一条记录),我们通过该对象来获取groupname
print(obj.group.groupname) return HttpResponse('ok')
当我们查询一个带有外键的表的记录时,Django会自动关联查询外键指向的表(UserGroup),并将对应的记录存放到一个对象中(UserGroup一条记录),我们通过该记录可以获取外键指向的表中的信息(groupname)。
def orm_test(request):
# 查询数据,返回的result是QuerySet类型,实际上相当于一个列表,每个元素是一个对象,相当于 select * from cmdb_userinfo;
result = models.UserInfo.objects.all()
# 便利result中的每个对象,其中每列对应一个成员属性
for row in result:
print(row.id, row.username, row.password)
return HttpResponse('ok')
[Python自学] day-19 (2) (Django-ORM)的更多相关文章
- Python全栈之路--Django ORM详解
ORM:(在django中,根据代码中的类自动生成数据库的表也叫--code first) ORM:Object Relational Mapping(关系对象映射) 我们写的类表示数据库中的表 我们 ...
- python的Web框架,Django的ORM,模型基础,MySQL连接配置及增删改查
Django中的ORM简介 ORM概念:对象关系映射(Object Relational Mapping,简称ORM): 用面向对象的方式描述数据库,去操作数据库,甚至可以达到不用编写SQL语句就能够 ...
- python 终级篇 django ---ORM操作
一般操作 必会的 ...
- [Python自学] day-18 (2) (MTV架构、Django框架、模板语言)
一.实现一个简单的Web服务器 使用Python标准库提供的独立WSGI服务器来实现MVC架构. 首先,实现一个简单的Web服务器: from wsgiref.simple_server import ...
- Python自动化之django orm之Q对象
Python自动化之django orm之Q对象 什么是Q对象? Encapsulates filters as objects that can then be combined logically ...
- 【python】-- Django ORM(基础)
Django ORM(基础) Django 框架十分强大,自带数据库操作功能.Django 跟 SQLAchemy 一样,也是通过ORM(Object Relational Mapping,关系对象映 ...
- Python - 自学django,上线一套资产管理系统
一.概述 终于把公司的资产管理网站写完,并通过测试,然后上线.期间包括看视频学习.自己写前后端代码,用时两个多月.现将一些体会记录下来,希望能帮到想学django做web开发的人.大牛可以不用看了,小 ...
- python web框架Django——ORM
ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射”的简称 ...
- 【python】-- Django ORM(进阶)
Django ORM(进阶) 上一篇博文简述了Django ORM的单表操作,在本篇博文中主要简述Django ORM的连表操作. 一.一对多:models.ForeignKey() 应用场景:当一张 ...
- python 之 Django框架(orm单表查询、orm多表查询、聚合查询、分组查询、F查询、 Q查询、事务、Django ORM执行原生SQL)
12.329 orm单表查询 import os if __name__ == '__main__': # 指定当前py脚本需要加载的Django项目配置信息 os.environ.setdefaul ...
随机推荐
- Linux基础 目录
一,linux入门介绍 二,界面目录介绍 三,vim使用 四,文件管理. 文件夹管理. 五.用户创建流程.用户管理 .组管理 六.权限管理.软连接/硬链接 七.磁盘管理 八.软件包的管理 九.系统服务 ...
- fiddler笔记:快捷工具栏
WinConfig: Comment 为所有选中的Session添加Comment. Replay Replay+ctrl 重新发送请求,而不包括任何条件请求头. Replay+shift 指定每 ...
- 怎样设置cookie生效的域名和路径
Domain 属性指定浏览器发出HTTP请求时, 哪些域名需要附带这个Cookie. 比如 Domain 设置为 example.com, 那 abc.example.com 也会在发起请求时附带这个 ...
- SqlServer学习之存储过程
前言:对于存储过程一直有一种抵触的心理,因为毕业至今所在的公司开发组都不是很规范,对于开发的一些注意事项并没有很多的规定,只是在知乎上查找相关知识的时候,看到很多人对于在程序里使用存储过程的不好之处都 ...
- SpringBoot整合Redis---Jedis版
目录 介绍 开发环境 pom文件引入 创建redis.properties配置文件 创建RedisConfig配置类 创建RedisUtil工具类 使用 效果 介绍 Redis简介 Redis 是完全 ...
- Cron 表达式详解
Crontab Crontab简介 crontab命令常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令.该命令从标准输入设备读取指令,并将其存放于"crontab&quo ...
- NSInvocation简单总结
(1)用法 NSInvocation是调用函数的另一种方式,它将调用者,函数名,参数封装到一个对象,然后通过一个invoke函数来执行被调用的函数,其思想就是命令者模式,将请求封装成对象. 例如,有这 ...
- 2.第一个MyBatis程序
1.导入jar包 2.定义实体类 3.创建对应的表 4.定义Dao接口 public interface StudentDAO { public void saveStudent(Student s) ...
- python 中startswith()和endswith() 方法
startswith()方法 Python startswith() 方法用于检查字符串是否是以指定子字符串开头如果是则返回 True,否则返回 False.如果参数 beg 和 end 指定值,则在 ...
- late_initcall 替换 module_init
今天在调试pwm驱动程序的时候,在__init函数中调用pwm_init后,则以太网不可用.pwm_init放在设备文件的open函数中,则系统正常运行. 这当中的区别就是硬件初始化函数pwm_ini ...