- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
Django2.0版本ORM实操都在这里👆👆👆👆👆 Django请求生命周期是什么?进来看了就明白 Django2.0版本路由和有名无名分组到底和Django1.0版本有什么区别?如何实现反向解析?我已经总结好了~
ORM:对象映射关系程序
通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,而不用直接使用sql语言;
python与MySQL映射关系
Python | 映射 | MySQL |
---|---|---|
类 | -------> | 表 |
对象 | -------> | 表里面的数据 |
对象点属性 | -------> | 字段对应的值 |
✨我们的模型类需要写在应用下的models.py文件中
# SQL原生语句和ROM创建的区别
class User(models.Model):
# id int primary key auto_increment
id = models.AutoField(primary_key=True)
# name varchar(32)
name = models.CharField(max_length=32) # CharField必须要加max_length参数
# age int
age = models.IntegerField()
✨✨✨数据库迁移命令(重点)
models.py
文件执行了和数据库相关的命令,就重新执行下面这两条命令:python3 manage.py makemigrations、python3 manage.py migrateRUN manage.py Task
,输入makemigrations
1.将数据库修改操作先记录到"本本"(对应应用下的migrations文件夹)
python3 manage.py makemigrations
# 执行完,产生一个文件,用来记录
2.真正的执行数据库迁移操作,同步到数据库
python3 manage.py migrate
# 执行完会在数据库中产生Django所需的依赖表,自动创建的
# 自己创建的表user以'应用名_表名'的形式创建,app01_user
✨✨不指定id字段和主键等,ORM会自动创建id
# 如果你不指定主键 那么orm会自动帮你创建一个名为id的主键字段
class user(models.Model):
username = models.CharField(max_length=32)
# 就不用写id了···,需要定制id,就写上~
# 原来的表
class user(models.Model):
username = models.CharField(max_length=32)
# 增加字段(两种方法)
password = models.IntegerField('密码',null=True) # 该字段可以为空
is_delete = models.IntegerField(default=0) # 默认值
# 修改字段
直接改代码,然后执行makemigrations,数据库迁移
# 删除
直接删除或者注释掉代码,然后执行makemigrations,数据库迁移
查询操作
username = request.POST.get('username')
# 获取用户post从页面提交的数据,username是获取到用户提交的数据
# 1.查询数据
# select * from user where name=username;
user_obj_list = models.User.objects.filter(name=username) # 获取到的是列表,看成列表套数据对象
obj_info = user_obj_list[0]
# 获取id、name、age
print(obj_info.id,
obj_info.name,
obj_info.age) # 1 hammer 18
# 或这下面这样提取列表数据也可以
user_obj = models.User.objects.filter(name=username).first()
'''如果用户提交的信息不存在返回None'''
# 登录功能示例
user_check = models.User.objects.filter(name=username,password=password).first() # 等价于select * from user where name=username and pwd = password
if user_check:
return HttpResponse('登录成功')
# 2.添加数据
# insert into user(name,pwd) values(username,password);
models.User.objects.create(name=username,pwd=password)
# 3.查询所有的数据,展示所有数据到前端页面,通过for循环在html页面获取表数据
# select * from user;
models.User.objects.all() # 返回列表[obj1,obj2,obj3,obj4]
# 4.修改数据
models.User.objects.filter(id=edit_id).update(name=username,pwd=password)
# 或者
edit_obj.name = username
edit_obj.pwd = password
edit_obj.save()
# 5.删除数据
models.User.objects.filter(id=delete_id).delete()
python manage.py makemigrations
inspectdb 表名
语句反向操作数据库,反向输出sql语句对应的类
ps:如果inspectdb
后不跟表名,那么就会将该数据库内的所有表反向解析成类(python语句)
# 数据库里面已经有一些表,我们如何通过django orm操作?
1.照着数据库表字段自己在models.py
2.django提供的反向同步
操作:
1.先执行数据库迁移命令 完成链接
python manage.py makemigrations
2.查看代码
python manage.py inspectdb
class Userinfo(models.Model):
id = models.IntegerField(blank=True, null=True)
name = models.CharField(max_length=32, blank=True, null=True)
pwd = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'userinfo'
表与表之间的关系有一下三种:
一对多、多对多、一对一,没关系暂且排外,下面演示如何通过ORM来创建外键确立表关系~
ORM创建外键字段的位置:
一对多:创建在多的一方
一堆一:创建在任何一方都可以,但是推荐创建在查询频率较高的表中
多对多(两种方式):
自己创建第三张表
创建在任何一方都可以,但是推荐创建在查询频率较高
# 创建书籍表 出版者表 作者表
# 先写表的基本结构,在考虑表关系如何写外键
# 书籍表
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8, decimal_places=2) # 总共8位 小数占2位
# 作者外键
Author = models.ManyToManyField(to='Author')
# 出版社外键
Publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
# 作者表
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
Atuhor_Detail = models.OneToOneField(to='Atuhor_Detail',on_delete=models.CASCADE)
# 作者详情表
class Atuhor_Detail(models.Model):
phone = models.BigIntegerField()
Email = models.EmailField()
# 出版社表
class Publish(models.Model):
name = models.CharField(max_length=32)
address = models.CharField(max_length=32)
注意:
on_delete=models.CASCADE
,不然会报错,只有OneToOneField和ForeignKey需要写,ManyToManyField不需要# django 升级到2.0之后,表与表之间关联的时候,必须要写on_delete参数,否则会报异常:
# TypeError: init() missing 1 required positional argument: ‘on_delete’
Atuhor_Detail = models.OneToOneField(to='Atuhor_Detail',on_delete=models.CASCADE)
Publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
👉“江狗”
在新版本***Django2.x***中,url
的路由表示用path
和re_path
代替;
模块的导入由django1.x版本的from django.conf.urls import url,include
变成现在的Django2.x中的from django.urls import path, re_path, include
Django提供了两种设计URL的方法: path
和re_path
,它们均支持向视图函数或类传递参数。path
是正常参数传递,re_path
是采用正则表达式regex匹配;
path
方法:采用双尖括号<变量类型:变量名>
或<变量名>
传递,例如<int:id>
, <slug:slug>
或<username>
。re_path
方法: 采用命名组(?P<变量名>表达式)
的方式传递参数。path
支持匹配的数据类型只有str
,int
, slug
, uuid
四种。一般来说re_path
更强大,但写起来更复杂一些'''urls.py'''
from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
# 路由匹配
re_path(r'test',views.test),
re_path(r'testadd',views.testadd)
]
'''views.py'''
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
def test(request):
return HttpResponse('from test')
def testadd(request):
return HttpResponse('from testadd')
'''
这样匹配的话,相当于使用正则表达式,如果url后面写test返回fromtest,那么再写testadd呢?也会返回from test,这是一种包含关系,需要更明确的去区别,比如写test/,或者testadd/,建议在末尾加上/
'''
urlpatterns = [
path('admin/', admin.site.urls),
# 限制开头
re_path(r'^test/',views.test),
# 限制开头和结尾
re_path(r'^testadd/$',views.testadd)
]
/
,那么会自动补充/
,相当于跳转页面,如果不想使用该特性,可以在setting.py文件中取消:APPEND_SLASH = False
下例中,我们分别以path
和re_path
定以了两个urls,它们是等效的,把文章的id(整数类型)传递给了视图。re_path
里引号前面的小写r
表示引号里为正则表达式, ^
代表开头,$
代表以结尾,\d+
代表正整数
# blog/urls.py
from django.urls import path, re_path
from . import views
urlpatterns = [
path('blog/articles/<int:id>/', views.article_detail, name = 'article_detail'),
re_path(r'^blog/articles/(?P<id>\d+)/$', views.article_detail, name='article_detail'),
]
# blog/views.py
def article_detail(request, id):
# 展示某篇文章
在使用path
和re_path
方法设计urls需注意:
/
,但建议以斜杠结尾;re_path
时不一定总是以$
结尾,有时不能加。比如下例中把blog.urls
通过re_path
加入到项目urls中时就不能以$
结尾,因为这里的blog/
并不是完整的url,只是一个开头而已。from django.urls import include, re_path
urlpatterns = [
re_path(r'^blog/', include('blog.urls')),
...
]
涉及到urls.py写对应关系,无名分组后如果不给视图函数传参,那么就会报错
通俗理解:路由使用正则,正则匹配加括号分组,当作了视图函数的第二个位置参数
'''urls.py'''
from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
# 匹配数字
# re_path(r'^test/[0-9]{4}/$',views.test),
# 无名分组,匹配1个到多个正整数
re_path(r'^test/(\d+)/$',views.test),
]
'''views.py'''
def test(request,num):
print(num) # 1234
return HttpResponse('from test')
'''路由使用正则,正则匹配加括号分组,当作了视图函数的第二个位置参数'''
在使用路由的时候,正则表达式可以起别名,别名当作关键字参数传给视图函数;
没有按关键字参数写报错
按别名,传参
'''urls.py'''
urlpatterns = [
re_path(r'^test/(?P<id>\d+)/$',views.test),
]
'''views.py'''
def test(request,id):
print(id)
return HttpResponse('from test')
# 有名分组,将匹配到的数字命名成id,当成关键字参数传给视图函数
注意:
re_path(r'^test/(\d+)/(?P<id>\d+)/$',views.test)
def test(request,a,id):
print(a,id)
return HttpResponse('from test')
# 这样不可以
re_path(r'^testadd/(\d+)/(\d+)/$',views.testadd)
def testadd(request,*args,**kwargs):
return HttpResponse('from testadd')
# 这样使用相同分组是可以的
反向解析解决了当路由频繁变化的时候,html界面上的连接地址实现动态解析;
'''urls.py'''
# 1、给路由与视图函数对应关系添加一个别名
from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
# 反向解析
path('index/',views.index,name='index_name'),
path('home/',views.home)
]
'''views.py'''
from django.shortcuts import HttpResponse,render,reverse
def index(request):
return HttpResponse('from index')
def home(request):
print(reverse('index_name'))
# 或者
# return redirect('index_name')
return render(request,'home.html')
'''home.html'''
<a href="{% url 'index_name' %}">111</a>
<a href="{% url 'index_name' %}">111</a>
<a href="{% url 'index_name' %}">111</a>
总结:
当路由频繁变化的时候,html界面上的连接地址如何做到动态解析
# 1.给路由与视图函数对应关系添加一个别名(名字自己指定 只要不冲突即可)
re_path(r'^index/',views.index,name='index_name')
# 2.根据该别名动态解析出一个结果,该结果可以直接访问到对应的路由
前端
<a href="{% url 'index_name' %}">111</a>
后端
from django.shortcuts import reverse
reverse('index_name')
ps:redirect括号内也可以直接写别名
如果有分组的情况,不写数字参数会报错
'''路由'''
urlpatterns = [
path('admin/', admin.site.urls),
# 反向解析
re_path(r'index/(\d+)/',views.index,name='index_name'),
path('home/',views.home)
]
'''后端'''
def index(request):
return HttpResponse('from index')
def home(request):
print(reverse('index_name'))
return render(request,'home.html')
'''前端'''
<a href="{% url 'index_name' %}">111</a>
无名分组反向解析
# 无名分组
1、起别名
re_path(r'^index/(\d+)/',views.index,name='index_name')
2、前端
<a href="{% url 'index_name' 1 %}"></a> # 只要给个数字即可
3、后端
reverse('index_name',args=(1,)) # 只要给个数字即可
有名分组反向解析
# 无名分组
1、起别名
re_path(r'^index/(?P<id>\d+)/',views.index,name='index_name')
2、前端
<a href="{% url 'index_name' id=1 %}"></a> # 只要给个数字即可
3、后端
reverse('index_name',kwargs={'id':1}) # 只要给个数字即可
总结:
url
和Django1.0一样,一定要区别开来def index(request,id):
return render(request,'home.html')
# id一般是获取到的主键值
👉参考文献:大江狗
我对 Python-Django 和 web 开发还很陌生,我被困在这个使用 POST 创建新资源的特殊问题上。 我正在为 REST API 使用 Django REST 框架,我正在尝试创建一个新资
我已经使用 Django-storages 成功地将 Word 文档存储到 S3。 class Document(TitleSlugDescriptionModel, TimeStampedModel
我有 2 个关于模型代理的问题, 如何从模型对象创建代理对象? 如何从模型查询集创建代理查询集? 例如,假设我们定义了: from django.contrib.auth.models import
我想编写一个直接执行 HTTP 请求的单元测试(而不是使用 django.test.client.Client)。 如果您好奇为什么 - 那是因为我想测试我从 Django 应用程序公开的 Thrif
我为我的个人网站启动了一个 django 项目来学习 django。到目前为止,我已经将我的开发环境设置为我需要的一切,并遵循 this很棒的教程来创建一些基本的数据结构和模板。现在我想开始使用我之前
我已经阅读了很多关于如何在使用 Django 注册时添加额外字段的信息,例如 here 、 here 和 here 。代码片段是: forms.py(来自注册应用程序) class Registrat
我正在编写小型社交应用程序。功能之一是在网站标题中写入用户名。因此,例如,如果我登录并且我的名字是Oleg(用户名),那么我应该看到: Hello, Oleg | Click to edit prof
我有一个使用 Django 和 Django Rest 框架开发的应用程序。我想将 django-reversion 功能添加到我的应用程序中。 我已经尝试过http://django-reversi
我有一个简单的 HTML 表单,我没有使用 Django 表单,但现在我想添加一个选择。 选择最容易创建为 Django ChoiceField (与通过循环等手动创建选择相反),但是,如果没有在 D
我不明白为什么人们以两种方式编写外键,这样做的目的是什么?它们是相同还是不同? 我注意到有些人这样写: author = models.ForeignKey(Author, on_delete=mod
我想在我的 Django 应用程序中获取评论最多的十个帖子,但我做不到,因为我想不出合适的方法。 我目前正在使用 django 评论框架,并且我已经看到使用 aggregate or annotate
这对于 Django 1.2 仍然有效吗? Custom Filter in Django Admin on Django 1.3 or below 我已经尝试过,但管理类中的 list_filter
问题在于,当 django-compressor 编译为 .js 文件的 CoffeeScript 文件中引用 {{ STATIC_URL }} 时,它无法正确加载。 在我的 django 模板中,我
我正在尝试将一些字段从一个 django 模型移动到一个新模型。假设我有一个书籍模型: class Book(models.Model): title = models.CharField(max
我想在我的 Django 应用程序中获取评论最多的十个帖子,但我做不到,因为我想不出合适的方法。 我目前正在使用 django 评论框架,并且我已经看到使用 aggregate or annotate
目前我正在寻找在 Django 中实现访问控制。我已经阅读了有关内置权限的内容,但它并不关心每个对象的基础。例如,我想要“只有创建者可以删除自己的项目”之类的权限。所以我读到了 django-guar
嗨,我正在将我的 Django 模型的一个字段的值设置为其他模型的另一个字段的值。这个值应该是动态变化的。 这是我的第一个模型 class MainModel(AbstractBaseUser, Pe
我正在尝试为我的模型创建一个编辑表单。我没有使用模型表单,因为根据模型类型,用户可以使用不同的表单。 (例如,其中一个表单有 Tinymce 小部件,而另一个没有。) 有没有什么方法可以使用模型设置表
Django 模板中的搜索字段 如何在类似于此图像的 Django 模板中创建搜索字段 http://asciicasts.com/system/photos/1204/original/E354I0
根据 Django documentation ,如果 Django 安装激活了 AuthenticationMiddleware,HttpRequest 对象有一个“user”属性代表当前登录的用户
我是一名优秀的程序员,十分优秀!