Python框架☞Django
1 settings.py文件 2 3 #默认使用sqlite3数据库 4 DATABASES = { 5 'default': { 6 'ENGINE': 'django.db.backends.sqlite3', 7 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 8 } 9 } 10 11 #使用其他数据库连接 12 DATABASES = { 13 'default': { 14 'ENGINE': 'django.db.backends.postgresql', 15 'NAME': 'mydatabase', 16 'USER': 'mydatabaseuser', 17 'PASSWORD': 'mypassword', 18 'HOST': '127.0.0.1', 19 'PORT': '5432', 20 } 21 } 22 23 ENGINE包括: 24 'django.db.backends.postgresql' 25 'django.db.backends.mysql' 26 'django.db.backends.sqlite3' 27 'django.db.backends.oracle' 28 ********注意******* django默认使用MySQLdb模块连接mysql python3中没有MySQLdb模块 所以django中连接mysql时需要如下操作: 在project同名下的__init__文件操作: import pymysql pymysql.install_as_MySQLdb() 29 详情参看:https://docs.djangoproject.com/en/2.2/ref/settings/#databases
1 # 全部字段: 2 __all__ = [ 3 'AutoField', 'BLANK_CHOICE_DASH', 'BigAutoField', 'BigIntegerField', 4 'BinaryField', 'BooleanField', 'CharField', 'CommaSeparatedIntegerField', 5 'DateField', 'DateTimeField', 'DecimalField', 'DurationField', 6 'EmailField', 'Empty', 'Field', 'FieldDoesNotExist', 'FilePathField', 7 'FloatField', 'GenericIPAddressField', 'IPAddressField', 'IntegerField', 8 'NOT_PROVIDED', 'NullBooleanField', 'PositiveIntegerField', 9 'PositiveSmallIntegerField', 'SlugField', 'SmallIntegerField', 'TextField', 10 'TimeField', 'URLField', 'UUIDField', 11 ] 12 13 # 常用字段介绍 ############## AutoField BooleanField DateField #日期类型 date DateTimeField #日期类型 datetime CharField URLField # 数据库中是String类型 EmailField # 数据库中是String类型 FloatField IntegerField ....
1 # 字段参数 2 verbose_name=None 3 name=None 4 primary_key=False 5 max_length=None 6 unique=False 7 blank=False 8 null=False, 9 db_index=False, 10 rel=None, 11 default=NOT_PROVIDED, 12 editable=True, 13 serialize=True, 14 unique_for_date=None, 15 unique_for_month=None, 16 unique_for_year=None, 17 choices=None, 18 help_text='', 19 db_column=None, 20 db_tablespace=None, 21 auto_created=False, 22 validators=(), 23 error_messages=None 24 25 26 # 字段参数解释 27 null: 数据库中是否可以为空 28 default: 默认值 29 primary_key: 主键 30 db_column: 数据库中表的列名 31 db_index: 字段是否为索引 32 unique: 唯一索引 33 choices: django admin中显示下拉框; 避免链表查询(链表查询效率低) 34 user_type_choices = ( 35 (1, '管理员'), 36 (2, '运维'), 37 (3, '普通用户') 38 ) 39 user_type_id = models.IntergerField(choices=user_type_choices) 40 auto_now: 更新时自动生成 41 auto_now_add: 创建时 自动更新为当前时间 42 blank: django admin中是否可以为空 43 verbose_name: django admin中是显示中文 44 editable: django admin中是否可以编辑 45 error_messages: django admin中是输入错误时提示语, 语法 error_messages={'required':'请输入信息'} 46 help_text: django admin中提示 47 validators: django form 自定义错误信息 48 to: 外键&多对多关联的表 49 on_delete: 外键必传参数,对应的value有(CASCADE、PROTECT、DO_NOTHING、SET、SET_NULL、SET_DEFAULT) CASCADE: PROTECT: SET_NULL: 需要设置同时设置null=True SET_DEFAULT: 需要同时设置default的值 DO_NOTHING: SET(): 需要设置一个默认值 from django.conf import settings from django.contrib.auth import get_user_model from django.db import models def get_sentinel_user(): return get_user_model().objects.get_or_create(username='deleted')[0] class MyModel(models.Model): user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.SET(get_sentinel_user), )
1 1. 独立表, 跟其他表没有关联 2 2. 一对多关系创建表,使用ForeignKey字段 3 3. 多对多关系创建表: 4 方法1.自定义第三章表【使用外键】,表的列数无限制 5 方法2.django帮助写第三章表,使用ManyToManyField字段,列限制只有3列;models.ManyToManyField(to="FOO")
1 # django项目,数据库中表名默认是按照 appName_modelsName 小写命名的,如果想修改数据库的表名 则需要在models中添加如下代码 2 3 class Roles(models.Model): 4 """ 5 角色表 6 """ 7 title = models.CharField(max_length=16, null=False, db_column="name") 8 9 # 添加如下代码,数据库中表的名称就变为roles 10 class Meta: 11 db_table = "roles"
1 # 获取choices显示值语法: get_FOO_display() 2 3 # models结构 4 from django.db import models 5 6 class User(models.Model): 7 username = models.CharField(max_length=32, null=False) 8 password = models.CharField(max_length=32, default=123456) 9 nickname = models.CharField(max_length=64, unique=True, null=False) 10 sex = ( 11 (1, '男'), 12 (2, '女'), 13 ) 14 femal = models.IntegerField(default=1, choices=sex) 15 16 def __str__(self): 17 return self.nickname 18 19 # 数据库中信息 20 id username password nickname femal 21 1 yunzhong 123456 流星 1 22 2 anjing 123456 静好 2 23 3 mingbai 666666 明白 1 24 25 26 27 # 获取choices的值 28 obj = User.objects.all() 29 for item in obj: 30 print(item.nickname, item.get_femal_display())
1 跨表查询分为:正向查询&反向查询 2 正向查询:class中有ForeignKey 或者 ManyToManyField字段,这张表通过外键 或者 多对多关系跨向另外一张表进行查询,这种查询可以理解为正向查询 3 4 方向查询:class被其他class关联,但表中没有ForeignKey 或 ManyToManyField字段,通过表名小写_set 跨向另外一张表(这里小写的表名指的是主动关联的表名),这种查询可以理解为反向查询 5 6 正向跨表查询方式: 7 1. foreignKey__field # 双下划线, values、values_list使用 8 2. obj.foreign_key.field #all()查询之后,继续打印输入 9 10 反向跨表查询方式: 11 1. 表名小写_set # all()查询,然后打印输出,实际使用 表名小写_set.all() 12 2. 表名小写 # values_list、 values 13 3. 表名小写__field # values、 values_list
1 django路由配置支持三种形式: 2 1. FBV(function base view) 3 2. CBV(class base view) 4 3. Including another URLconf 5 6 一、FBV配置 7 *****urls.py code***** 8 from django.urls import path 9 from app01 import views 10 urlpatterns = [ 11 path('go/', views.go_to), 12 ] 13 14 *****views code***** 15 def go_to(request): 16 pass 17 18 二、CBV配置 19 *****urls.py code***** 20 from django.urls import path 21 from business import views 22 urlpatterns = [ 23 path('message/', views.Message.as_view(), name='message'), # name用于反向生成url 24 ] 25 26 *****views code***** 27 # 此处的class需要继承View类 28 from django.views import View 29 class Message(View): 30 31 def dispatch(self, request, *args, **kwargs): 32 """ 33 用于分发请求,不同的请求调用不同的method 34 :param request: 35 :param args: 36 :param kwargs: 37 :return: 38 """ 39 pass 40 41 def get(self): 42 pass 43 44 def post(self): 45 pass 46 47 三、Including another URLconf配置有2种方案 48 方案1:全部配置在主项目的urls.py中 49 方案2:主项目urls.py和 app中均需要配置 50 51 具体实现: 52 1.全部在主项目urls.py中配置 53 from business import views as busin_views 54 extra_patterns = [ 55 path('reports/', busin_views.report, {'blog_id': 3}), 56 ] 57 58 urlpatterns = [ 59 path('business/', include(extra_patterns)), 60 ] 61 62 2.主项目urls.py和 app中均需要配置 63 ***主项目urls.py code***** 64 urlpatterns = [ 65 path('crm/', include('crm.urls', namespace='crm_reverse')), 66 ] 67 68 ***app中需要创建一个urls.py 内部code******* 69 from django.urls import path, re_path, include 70 from . import views 71 72 app_name = 'crm' 73 74 urlpatterns = [ 75 path('', views.home), 76 path('read/', views.read), 77 ] 78 79 ========================= 80 django路由系统还支持正则、传参、反向生成URL、去除冗余等配置 81 from django.urls import path, register_converter 82 register_converter(converters.FourDigitYearConverter, 'yyyy') #自定义参数使用 83 urlpatterns = [ 84 path('admin/', admin.site.urls), 85 path('message/', views.Message.as_view(), name='message'), 86 path('home/<int:year>/<int:month>/', views.home, name='home_page'), # name用于反向生成URL 87 path('index/<slug:slug>/', views.index, name='reverse_index'), #slug指非固定格式 88 89 path('articles/<yyyy:year>/', views.year_archive, {'foo': 'bar'}), # yyyy为自定义参数类型,需要结合其他代码 90 91 re_path(r'^luck/([0-9]{4})/', views.luck), # 元组形式传参 92 re_path(r'^lucy/(?P<year>[0-9]{4})/', views.lucy), # 字典形式传参 93 re_path(r'^comments/(?:page-(?P<page_number>\d+)/)?$', views.comments), 94 path('hello/django/', include([ # 去除冗余 95 path('history/', views.history), 96 path('edit/', views.edit), 97 ])), 98 ] 99 100 101 自定义参数类型对应converters code: 102 class FourDigitYearConverter: 103 regex = '[0-9]{6}' 104 105 def to_python(self, value): 106 return int(value) 107 108 def to_url(self, value): 109 return '%04d' % value
1 cookie & session 2 { 3 http是短连接 4 cookie: 5 独立存在,用户浏览器上存储的键值对, cookie跟登陆没直接关系 6 以后每次请求 都会带着以前的cookie 7 所有系统--->用户登录是基于cookie做的 8 基于cookie可以做用户认证 9 cookie的来源: 服务端设置 10 关键信息保存在cookie,会泄漏 会被篡改 11 12 session 13 服务器端保存的键值对,键值对的key是随机字符串 14 用户请求过来后,用户的cookie中会携带随机字符串 15 16 Django框架中session支持保存位置:缓存、缓存+数据库、文件、数据 库、加密cookie; 默认保存在数据库 17 默认不支持redis,支持memcache 18 Django中session的有效期默认是2周,可以在setting中进行配置 19 """ 20 Django中的request.session['user']= u 会同时做如下事情: 21 1.生成随机字符串 22 2.发给客户端 23 3.保存在服务端 24 4.并在服务端写用户名 25 """ 26 27 django_session可设置de点: 28 1.session_id 29 2.是否基于安全传输(https) 30 3.cookie是否可以修改 31 4.cookie有效时间 32 5.关闭浏览器 cookie是否自动失效 33 6.cookie全站生效 34 7.是否每次请求都保存cookie 35 ... 36 37 网站注销: 38 注销前 需要清除session # request.session.clear() 39 } 40 41 在setting中设置Django的session: 42 SESSION_ENGINE 43 SESSION_COOKIE_AGE 44 SESSION_COOKIE_DOMAIN 45 SESSION_COOKIE_NAME 46 SESSION_COOKIE_PATH 47 SESSION_COOKIE_SECURE 48 SESSION_EXPIRE_AT_BROWSER_CLOSE 49 SESSION_SAVE_EVERY_REQUEST 50 SESSION_FILE_PATH 51 SESSION_CACHE_ALIAS # using cache-based session storage, this selects the cache to use. 52 53 详情参考: https://docs.djangoproject.com/en/2.2/ref/settings/#session-cookie-httponly
1 django后端可以分为3部分:中间件、路由、视图函数 2 3 中间件在django中的本质就是一个类 4 5 注意:中间件中的process_reponse function必须有返回值 6 7 中间件的作用: 8 1. 获取用户IP,黑名单中的IP不允许访问视图函数 9 2. 记录用户访问日志 10 3. 记录函数性能,记录执行时间 11 4. session校验 12 13 中间件可以定义方法: 14 def process_request(self, request): 15 def process_view(self, request, callback, callback_args, callback_kwargs): 16 def process_exception(request, exception) 17 def process_template_response(request, response) 18 def process_response(self, request, response): 19 详情参考:https://docs.djangoproject.com/en/2.2/topics/http/middleware/ 20 21 请求在中间件中执行流程: 22 0.中间件起点 23 执行所有中间件的process_request function--> 24 回到中间件起点 ---> 25 执行 所有中间件process_view function---> 26 执行路由&视图 27 从下到上依次执行所有中间件的process_exception function(程序有异常 才会执行) 28 回到中间件最后面 29 从下到上依次执行中间件process_response function
1 缓存目的:减少对数据库的操作(针对数据不经常变化,第一次请求完成后将数据放入缓存,后续有新请求进来直接从缓存拿数据,没必要重复操作数据库)。 2 3 Django默认支持缓存,使用自带缓存前需要进行配置。 4 Django支持的缓存有6种方式: 5 1.开发调试,不在任何地方存储 6 2.内存 7 3.文件 8 4.数据库 9 5.memcache(依赖python-memcache模块) 10 6.memcache(依赖pylibmc模块) 11 12 Django缓存配置: 13 在setting文件中添加如下代码: 14 CACHES = { 15 'default': { 16 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎 17 'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期) 18 'OPTIONS':{ 19 'MAX_ENTRIES': 300, # 最大缓存个数(默认300) 20 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) 21 }, 22 'KEY_PREFIX': '', # 缓存key的前缀(默认空) 23 'VERSION': 1, # 缓存key的版本(默认1) 24 'KEY_FUNCTION' 函数名 # 生成key的函数(默认函数会生成为:【前缀:版本:key】) 25 } 26 } 27 28 实际在使用过程中,根据使用的缓存策略不同, 替换对应的引擎即可。 29 Memcache引擎: 30 # using the python-memcached binding: 31 'default': { 32 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 33 'LOCATION': '127.0.0.1:11211', 34 } 35 36 # using the python-memcached binding: 37 CACHES = { 38 'default': { 39 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 40 'LOCATION': 'unix:/tmp/memcached.sock', 41 } 42 } 43 44 #using the pylibmc binding 45 CACHES = { 46 'default': { 47 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 48 'LOCATION': '/tmp/memcached.sock', 49 } 50 } 51 52 #Memcached instances running on IP address 172.19.26.240 and 172.19.26.242, both on port 11211: 53 CACHES = { 54 'default': { 55 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 56 'LOCATION': [ 57 '172.19.26.240:11211', 58 '172.19.26.242:11211', 59 ] 60 } 61 } 62 63 #DB引擎 64 CACHES = { 65 'default': { 66 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 67 'LOCATION': 'my_cache_table', 68 } 69 } 70 71 #Before using the database cache, you must create the cache table with this command: 72 python manage.py createcachetable 73 74 #文件引擎 75 CACHES = { 76 'default': { 77 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', 78 'LOCATION': 'c:/foo/bar', 79 } 80 } 81 82 #内存引擎 83 CACHES = { 84 'default': { 85 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 86 'LOCATION': 'unique-snowflake', 87 } 88 } 89 90 91 Django支持缓策略: 92 1.单个视图缓存---> 装饰器 93 2.局部缓存 94 3.全站缓存--->需要依赖中间件 95 96 a. 单个视图缓存 97 方式1: 98 from django.views.decorators.cache import cache_page 99 100 @cache_page(300) #参数指 超时时间 101 def home_view(request): 102 ... 103 方式2: 104 from django.views.decorators.cache import cache_page 105 from business import views as busin_views 106 urlpatterns = [ 107 path('home/', cache_page(300)(busin_views.home)), 108 ] 109 110 b.局部视图缓存 111 1.在模板最开始引入Templatetag 112 {% load cache %} 113 114 2.使用缓存 115 {% cache 300 cache_key %} # cache_key可以自定义 116 想要缓存内容 117 {% endcache %} 118 119 c.全栈缓存 120 在中间件的开始和结束的地方各加一个中间件。 121 有请求进来之后,经过一系列中间件,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户。当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存 122 MIDDLEWARE = [ 123 'django.middleware.cache.UpdateCacheMiddleware', 124 # 其他中间件... 125 'django.middleware.cache.FetchFromCacheMiddleware', 126 ] 127 128 ****自定义缓存****; 129 1.使用中间件/装饰器自定义操作 130 131 详情见: https://docs.djangoproject.com/en/2.2/topics/cache/#cache-arguments
1 django信号作用: 2 0.通过ORM进行数据库操作前,如果想进行一些操作,可以使用信号 3 1.信号能批量做操作 4 2.django程序启动完成之后,注册的信号应该已经可以使用。 5 即信号需要在程序运行前先加载完成;所以使用信号时,信号的相关代码建议写在同项目名同名下的__init__.py文件中 6 7 django内置信号: 8 一、Model signals: 9 1.django.db.models.signals.pre_init 10 2.django.db.models.signals.post_init 11 3.django.db.models.signals.pre_save 12 4.django.db.models.signals.post_save 13 5.django.db.models.signals.pre_delete 14 6.django.db.models.signals.post_delete 15 7.django.db.models.signals.m2m_changed 16 8.django.db.models.signals.class_prepared 17 18 二、Management signals 19 1.django.db.models.signals.pre_migrate 20 2.django.db.models.signals.post_migrate 21 22 三、Request/response signals 23 1.django.core.signals.request_started 24 2.django.core.signals.request_finished 25 3.django.core.signals.got_request_exception 26 27 四、Test signals 28 1.django.test.signals.setting_changed 29 2.django.test.signals.template_rendered 30 31 五、Database Wrappers 32 django.db.backends.signals.connection_created 33 34 详情见: https://docs.djangoproject.com/en/2.2/ref/signals/#module-django.db.backends 35 36 37 信号使用: 38 django.db.models.signals.pre_delete 39 40 def warn_pre_delete(sender, instance, using): 41 ''' 42 代码 43 ''' 44 pass 45 46 pre_delete.connect(warn_pre_delete )
1 django models中的class Meta介绍 2 Meta中的元选项: 3 abstract: 4 值为True时,对应的model不会在数据库中创建表, 5 如果model被继承,则model中的field会添加到子类中 6 7 app_label: 8 app没有在INSTALLED_APPS,注册的时候, model中需要指定当前model属于哪个app 9 10 db_table: 11 修改model在数据库中的表名,默认表名为appname_modelName(小写) 12 13 get_latest_by: 14 值为model中的一个字段 或者 多个字段列表,常用字段类型:日期、数字 15 设置之后 跟latest() and earliest() methods 配合使用 16 17 managed: 18 默认为True,执行migrate命令时会创建数据库以及执行migrations命令会生成缓存 19 设置为False后,执行migrate & migrations不会生效 20 21 order_with_respect_to: 22 和外键一起使用,对外键可排序, 值为外键字段 23 使用场景: 一对多 24 For example, if an Answer relates to a Question object, and a question has more than one answer, and the order of answers matters(顺序很重要), you’d do this: 25 26 from django.db import models 27 class Question(models.Model): 28 text = models.TextField() 29 # ... 30 31 class Answer(models.Model): 32 question = models.ForeignKey(Question, on_delete=models.CASCADE) 33 # ... 34 35 class Meta: 36 order_with_respect_to = 'question' 37 38 上述设计之后关联了4个方法: 39 get_RELATED_order() # RELATED is the lowercased model name 40 set_RELATED_order() 41 get_next_in_order() 42 get_previous_in_order() 43 44 实战: 45 >>> question = Question.objects.get(id=1) 46 >>> question.get_answer_order() 47 >>> question.set_answer_order([3, 1, 2]) 48 >>> answer = Answer.objects.get(id=2) 49 >>> answer.get_next_in_order() 50 >>> answer.get_previous_in_order() 51 52 ordering: 53 排序, 值是一个列表或者元组 54 ordering = ['-order_date'] 降序排列 55 ordering = ['pub_date'] 升序排列 56 ordering = ['?pub_date'] 随机排列 57 ordering = ['-pub_date', 'author'] pub_date 降序排列, 然后 author 升序排序 58 ordering = [F('author').asc(nulls_last=True)] 59 60 default_permissions: 61 默认对model的权限,默认值 ('add', 'change', 'delete', 'view') 62 可以自定制 63 64 indexes: 65 设置索引 66 from django.db import models 67 68 class Customer(models.Model): 69 first_name = models.CharField(max_length=100) 70 last_name = models.CharField(max_length=100) 71 72 class Meta: 73 indexes = [ 74 models.Index(fields=['last_name', 'first_name']), 75 models.Index(fields=['first_name'], name='first_name_idx'), 76 ] 77 78 unique_together: 79 设置联合唯一索引 80 格式: unique_together = [['driver', 'restaurant']] 或者 unique_together = ['driver', 'restaurant'] 81 82 index_together: 83 设置索引,可以不唯一 84 格式同unique_together 85 后续会被indexes替换掉 86 87 constraints: 88 2.2中的新功能 89 在model中想定义的约束条件 90 from django.db import models 91 92 class Customer(models.Model): 93 age = models.IntegerField() 94 95 class Meta: 96 constraints = [ 97 models.CheckConstraint(check=models.Q(age__gte=18), name='age_gte_18'), 98 ] 99 100 verbose_name: 101 django admin后台更可读的object 名字; 作用同verbose_name_plural,只不过verbose_name_plural优先级高一先。同时配置了verbose_name 和 verbose_name_plural之后, 显示的是verbose_name_plural的值 102 103 verbose_name_plural: 104 django admin后台使用,登录首页展示的app的name; 105 106 107 详情参考 https://docs.djangoproject.com/en/2.2/ref/models/options/
1 QuerySet可以被: 2 Iteration:迭代、 3 Slicing:切片、 4 len():获取长度、 5 list(): 6 bool():转化为list、判断是否为真 7 repr(): 交互模式下,querySet调用repr(),将对其求值。可以立即看到结果 8 Pickling/Caching: 做数据缓存 9 10 Methods that return new QuerySets: 11 filter() 12 #filter(**kwargs) 13 # 返回一个新querySet包含与给定查找参数匹配的对象 14 exclude() 15 #exclude(**kwargs) 16 # 排除... 17 annotate() 18 #annotate(*args, **kwargs) 19 order_by() 20 #order_by(*fields) 21 # 默认按model class meta中指定排序,也可以手动输入需要排序字段 22 Entry.objects.order_by(Lower('headline').desc()) 23 #asc() and desc() have arguments (nulls_first and nulls_last) that control how null values are sorted. 24 reverse() 25 # 将querySet的顺序倒排 26 distinct(): 27 #distinct(*fields) 28 #去除重复数据,等同于sql: select distinct() from tb_table 29 values(): 30 #values(*fields, **expressions) 31 方式1: 32 from django.db.models.functions import Lower, Upper 33 blogs = Blog.objects.values(lower_name=Lower('name')) 34 方式2: 35 from django.db.models import CharField 36 from django.db.models.functions import Lower 37 CharField.register_lookup(Lower) 38 Blog.objects.values('name__lower') 39 values_list(): 40 #values_list(*fields, flat=False, named=False) 41 #如果values_list中只有1个字段时,可以设置flat=True,返回值会是1个字段而非元组 42 #如果values_list中有多个字段,可以设置named=True,返回值元组会有一个统一的name 43 44 dates(): 45 #dates(field, kind, order='ASC') 46 #field必须是DateField类型 47 #kind值[year、month、week、day] 48 #order默认是ASC, 可以选择desc 49 #返回值时一个datetime.date类型 50 51 datetimes(): 52 #datetimes(field_name, kind, order='ASC', tzinfo=None) 53 54 none(): 55 #返回值为空, 结果是EmptyQuerySet的对象 56 #from django.db.models.query import EmptyQuerySet 57 58 all(): 59 60 union(): 61 #union(*other_qs, all=False) 62 #等同于SQL的 union, 默认只选择distinct值, 如果要允许重复值,设置all=True 63 #将两个querySet连接起来 64 65 difference(): 66 #difference(*other_qs) 67 #取的是a中存在b不存在的数据 68 #>>>qs1.difference(qs2, qs3) 69 70 select_related(): 71 #select_related(*fields) 72 73 prefetch_related() 74 #prefetch_related(*lookups) 75 76 extra() 77 extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None) 78 避免django无法写出一个负责的where字句,所以提供了此方法 79 #select 字段允许给查询字段设置别名, select的值需要是字典格式 eg: Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"}) 80 81 defer(): 82 # 排除 83 84 only(): 85 #只取only设置的字段 86 87 using(): 88 using(alias) 89 #数据库集群时使用 90 91 select_for_update() 92 select_for_update(nowait=False, skip_locked=False, of=()) 93 94 95 Methods that do not return QuerySets: 96 filter() 97 get(**kwargs): 98 create(): 99 get_or_create(): 100 obj, created = Person.objects.get_or_create( 101 first_name='John', 102 last_name='Lennon', 103 defaults={'birthday': date(1940, 10, 9)}, 104 )#除了名为defaults的可选选项之外,任何关键字参数都将在get调用中使用 105 106 update_or_create(defaults=None, **kwargs): 107 查询到数据,则使用default进行更新 108 obj, created = Person.objects.update_or_create( 109 first_name='John', last_name='Lennon', 110 defaults={'first_name': 'Bob'}, 111 ) 112 113 bulk_create(): 114 bulk_create(objs, batch_size=None, ignore_conflicts=False) 115 批量操作 116 方式1: 117 Entry.objects.bulk_create([ 118 ... Entry(headline='This is a test'), 119 ... Entry(headline='This is only a test'), 120 ... ]) 121 122 方式2: 123 from itertools import islice 124 125 batch_size = 100 126 objs = (Entry(headline='Test %s' % i) for i in range(1000)) 127 while True: 128 batch = list(islice(objs, batch_size)) 129 if not batch: 130 break 131 Entry.objects.bulk_create(batch, batch_size) 132 133 count(): 134 返回值时一个数字 135 136 latest()/earliest(): 137 基于给定字段返回表中最新对象 138 139 first()/last(): 140 第一条数据 141 142 aggregate(*args, **kwargs): 143 Returns a dictionary of aggregate values (averages, sums, etc.) calculated over the QuerySet 144 145 exists(): 146 update(): 147 delete(): 148 explain(): sql执行过程 149 150 151 字段查询: 152 exact、iexact 153 contains、icontains 154 in 155 gt\lt\gte\lte 156 startswith\istartswith 157 endswith\iendswith 158 range 159 date\year\iso_year\month\week\day\week_day\hour\minute\second 160 isnull 161 regex 162 163 Avg\Count\Max\Min\Sum
1 models: 2 class Blog(models.Model): 3 name = models.CharField(max_length=30) 4 tagline = models.TextField() 5 6 def __str__(self): 7 return self.name 8 9 10 class Author(models.Model): 11 name = models.CharField(max_length=200) 12 email = models.EmailField() 13 14 def __str__(self): 15 return self.name 16 17 18 class Entry(models.Model): 19 blog = models.ForeignKey(Blog, on_delete=models.CASCADE) 20 headline = models.CharField(max_length=255) 21 body_text = models.TextField() 22 pub_date = models.DateField() 23 mod_date = models.DateField() 24 authors = models.ManyToManyField(Author) 25 number_of_comments = models.IntegerField() 26 number_of_pingbacks = models.IntegerField() 27 rating = models.IntegerField() 28 29 def __str__(self): 30 return self.headline 31 F()说明: 32 # 比较同一个model中两个字段的value,可以使用F() 33 # F() objects 支持加法、减法、乘法、除法、模和幂运算 34 # F()支持按位运算 .bitand() .bitor() .bitrightshift().bitleftshift() 35 Entry.objects.filter(number_of_comments__gt=F('number_of_pingbacks')*2) 36 37 38 Q说明: 39 # filter\get\exclude中有多个关键字参数时,是以 and 形式进行查询,如果想执行更多的复杂查询(使用or查询),则需要用到Q, Q与~一起 表示 not 40 ~Q(pub_date__year=2005) 41 # 如果一个查询操作使用了两个Q object,则会生成一个新的Q object 42 #Q objects can be combined using the & and | operators 翻译:Q可以联合&、| 操作 43 Q(question__startswith='Who') | Q(question__startswith='What') 44 45 #filter\get\exclude 中既使用了关键字参数,又使用了Q object, 则Q必须在关键字参数之前 46 Poll.objects.get( 47 Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)), 48 question__startswith='Who', 49 ) 50 51 #filter\get\exclude中有多个Q时,Q与Q之间也是and查询 52 Poll.objects.get( 53 Q(question__startswith='Who'), 54 Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)) 55 )
1 创建 2 方式1:models.UserInfo.objects.create(username='', password='') #创建 UserInfo为类名 3 方式2:obj=models.UserInfo(username="", password="") 4 obj.save() 5 方式三:dic = {'username': '', 'password':''} 6 models.UserInfo.objects.create(**dic) 7 8 查询 9 方式1:models.UserInfo.objects.all() #查询表中全部字段 10 方式2:models.UserInfo.objects.values(username, password) #查询表中指定字段 11 方式3:models.UserInfo.objects.values_list(username, password) #查询表中指定字段 12 方式4:models.UserInfo.objects.filter(id=1) 13 方式4:models.UserInfo.objects.filter(username='admin', password='root') 14 方式4:models.UserInfo.objects.filter(id_gt=1) # 查询id>1 的数据 15 方式4:models.UserInfo.objects.filter(id_lt=1) # 查询id<1 的数据 16 方式5:models.UserInfo.objects.get(id=1) #只获取一条,,如果id不存在,程序报错 17 方式6:models.UserInfo.objects.all().order_by('-id') #按照id倒叙排列 18 方式7:models.UserInfo.objects.all().select_related('foreign_key') #查询自己&关联外键表的数据(使用left join 跨表查询) 19 方式7:models.UserInfo.objects.all().select_related('foreign_key', 'second_foreign_key') #查询自己&关联外键表的数据(使用left join 跨表查询) 20 方式8:models.UserInfo.objects.all().prefetch_related('foreign_key','second_foreign_key','....') #跨表查询会耗时,解决不想跨表&不想多次查询,会发2次单表sql请求 21 执行流程解析: 22 models.UserInfo.objects.all() 23 models.Part.objects.filter(id__in=[1,2,3,4]) #1,2,3,4表示上一条sql中的全部ID 24 25 删除 26 models.UserInfo.objects.all().delete() #删除全部数据 27 models.UserInfo.objects.filter(id=1).delete() #删除全部数据 28 更新 29 models.UserInfo.objects.all().update(password=99999) 30 models.UserInfo.objects.filter(id=1).update(password=99999) 31 32 补充: 33 34 性能相关查询: 35 0.select_related() #obj=models.UserInfo.objects.all().select_related('part', 'tb_name', ...) , 数据库中只查询一次 36 obj=models.UserInfo.objects.all() 37 for item in obj: 38 print(item.name, item.password, item.part_id, item.part.title) #每一个item.part.title都会进行一次数据库查询 39 40 1.prefetch_related() #解决性能问题 41 #obj=models.UserInfo.objects.all().prefetch_related('part','tb_name', ...) , 数据库中查询两次,每次都是单表查询 42 43 内部查询过程: 44 1.obj=models.UserInfo.objects.all() 45 2.obj=models.Part.objects.filter(id__in=) 46 47 其他: 48 2.models.UserInfo.objects.all().only('id', 'name') # querySet内部是一个个对象, 查询id、name 49 3.models.UserInfo.objects.all().defer('name') # querySet内部是一个个对象,不查询name字段 50 51 52 53 多对多关系创建表 54 { 55 56 方法1.自定义第三章表【使用外键】,表的列数无限制 57 方法2.django帮助写第三章表,使用ManyToManyField字段,列限制只有3列; 58 多对多跟本身的两张表没有关系 59 m=models.ManyToManyField(to="UserInfo") 60 61 # 对第三章表进行CURD操作 62 obj=models.UserGroup.objects.filter(id=1).first() 63 obj.m.add(1) #增加 64 obj.m.add(1,2,3,4) 65 obj.m.add(*[1,2,3]) 66 67 obj.m.remove(2)# 删除 68 obj.m.remove(2,3,4) 69 obj.m.remove(*[1,2]) 70 71 obj.m.clear() # 清空 72 73 obj.m.set([1,]) #更新 即 update,但会删除原数据 74 75 q=obj.m.all() # 获取到UserInfo表中的全部数据,返回值是queryset[obj,obj,obj,obj] 76 q=obj.m.filter(id__gt/id__lt=2) # 注意:此时filter对象是UserInfo,filter中id指的是userinfo表中的id 77 q=obj.m.values() 78 q=obj.m.values_list() 79 }
1 Django uses request and response objects to pass state through the system. 2 翻译:django使用request、response对象 通过系统传递状态 3 When a page is requested, Django creates an HttpRequest object that contains metadata about the request. Then Django loads the appropriate view, passing the HttpRequest as the first argument to the view function. 4 翻译:当一个页面被请求时,django创建了一个包含请求元数据的HTTPRequest对象。然后django加载对应的视图并将创建的HTTPRequest对象作为第一个参数传递给视图函数 5 6 HTTPRequest来源: from django.http.request import HttpRequest 7 8 HTTPRequest构造方法: 9 def __init__(self): 10 # WARNING: The `WSGIRequest` subclass doesn't call `super`. 11 # Any variable assignment made here should also happen in 12 # `WSGIRequest.__init__()`. 13 14 self.GET = QueryDict(mutable=True) 15 self.POST = QueryDict(mutable=True) 16 self.COOKIES = {} 17 self.META = {} #包含所有的http请求头 18 self.FILES = MultiValueDict() #文件上传,只有请求方式为POST且form表单有属性enctype="multipart/form-data"时,才能获取值 19 20 self.path = '' 21 self.path_info = '' 22 self.method = None 23 self.resolver_match = None 24 self.content_type = None 25 self.content_params = None 26 27 HTTPRequest详解 28 HttpRequest.FILES: 29 FILES will only contain data if the request method was POST and the <form> that posted to the request had enctype="multipart/form-data". Otherwise, FILES will be a blank dictionary-like object. 30 31 HttpRequest.META:一个包含所有可用信息请求头的字典,可用信息依赖客户端&服务端,具体包括: 32 CONTENT_LENGTH – The length of the request body (as a string). 33 CONTENT_TYPE – The MIME type of the request body. 34 HTTP_ACCEPT – Acceptable content types for the response. 35 HTTP_ACCEPT_ENCODING – Acceptable encodings for the response. 36 HTTP_ACCEPT_LANGUAGE – Acceptable languages for the response. 37 HTTP_HOST – The HTTP Host header sent by the client. 38 HTTP_REFERER – The referring page, if any. 39 HTTP_USER_AGENT – The client’s user-agent string. 40 QUERY_STRING – The query string, as a single (unparsed) string. 41 REMOTE_ADDR – The IP address of the client. 42 REMOTE_HOST – The hostname of the client. 43 REMOTE_USER – The user authenticated by the Web server, if any. 44 REQUEST_METHOD – A string such as "GET" or "POST". 45 SERVER_NAME – The hostname of the server. 46 SERVER_PORT – The port of the server (as a string). 47 48 HTTPRequest的属性方法: 49 headers 50 scheme 51 encoding 52 upload_handlers 53 body 54 55 HTTPRequest的普通方法: 56 get_host 57 get_port 58 get_full_path 59 get_full_path_info 60 get_signed_cookie 61 get_raw_uri 62 build_absolute_uri 63 parse_file_upload 64 close 65 read 66 readline 67 readlines 68 is_secure 69 is_ajax 70 71 详情参考: https://docs.djangoproject.com/en/2.2/ref/request-response/
1 django response 2 source: from django.http import HttpResponse 3 4 HTTPResponse构造方法: 5 HttpResponse.__init__(content=b'', content_type=None, status=200, reason=None, charset=None) 6 content:可迭代对象,通常是bytestring/string。其他类型会被转换成bytestring 7 content_type: MIMIE type,没设置则取默认值,默认值为:text/html; charset=utf-8 8 status: 响应码, 可以使用Python's http.HTTPStatus 9 reason: http响应短语,没有提供,则使用默认短语 10 charset:response使用的编码,如果没有设置,则从content_type提取,如果提取失败/不可用,则使用DEFAULT_CHARSET(utf-8) 11 12 HTTPResponse返回值: 13 1.返回字符串 14 from django.http import HttpResponse 15 >>> response = HttpResponse("Here's the text of the Web page.") 16 >>> response = HttpResponse("Text only, please.", content_type="text/plain") 17 >>> response = HttpResponse(b'Bytestrings are also accepted.') 18 19 2.以增量方式返回字符串 20 >>> response = HttpResponse('..........') 21 >>> response.write("<p>Here's the text of the Web page.</p>") 22 >>> response.write("<p>Here's another paragraph.</p>") 23 24 3.返回可迭代对象 25 26 4.设置response-header 27 >>> response = HttpResponse() 28 >>> response['Age'] = 120 29 30 5.告诉浏览器把response作为一个文件附件 31 >>> response = HttpResponse(my_data, content_type='application/vnd.ms-excel') 32 >>> response['Content-Disposition'] = 'attachment; filename="foo.xls"' 33 34 35 HTTPResponse普通方法: 36 HttpResponse.has_header(header) 37 HttpResponse.setdefault(header, value) 38 HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False, samesite=None) 39 HttpResponse.set_signed_cookie(key, value, salt='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False, samesite=None) 40 HttpResponse.delete_cookie(key, path='/', domain=None) 41 HttpResponse.close() 42 HttpResponse.write(content) 43 HttpResponse.flush() 44 HttpResponse.tell() 45 HttpResponse.getvalue() 46 HttpResponse.readable() 47 HttpResponse.seekable() 48 HttpResponse.writable() 49 HttpResponse.writelines(lines) 50 51 52 自定义response类: 53 from http import HTTPStatus 54 from django.http import HttpResponse 55 56 class HttpResponseNoContent(HttpResponse): 57 status_code = HTTPStatus.NO_CONTENT
1 django自定义simple_tag/filter步骤: 2 3 1.app在INSTALLED_APPS中注册 4 2.app下创建一个 templatetags Python package 5 3.templatetags下创建一个python file, file name不能与其他应用程序中自定义tags/filters冲突 6 app01/ 7 __init__.py 8 models.py 9 templatetags/ 10 __init__.py 11 poll_extras.py 12 views.py 13 4.在python file中必须有一个template.Library的实例且变量名为register 14 from django import template 15 register = template.Library() 16 5. 模板中导入格式: 17 {% load poll_extras %} 18 19 20 一、自定义template filters 21 django.template.Library.filter() 22 1.filter定义 23 2.注册filter register.filter('lower', lower) 24 25 自定义template filters就是一个包含一个或两个参数的python function 26 The value of the variable (input) – not necessarily a string. 27 The value of the argument – this can have a default value, or be left out altogether. 28 filter定义: 29 def cut(value, arg): 30 """Removes all values of arg from the given string""" 31 return value.replace(arg, '') 32 eg: {{ var|foo:"bar" }} 33 34 35 filter注册需要传递2个参数: 36 1.The name of the filter – a string. 37 2.The compilation function – a Python function (not the name of the function as a string). 38 filter注册: 39 register.filter('cut', cut) 40 41 也可以将register.filter()作为一个装饰器 42 @register.filter(name='cut') 43 def cut(value, arg): 44 return value.replace(arg, '') 45 46 @register.filter #如果没有指定name, django默认使用函数名代替 47 def lower(value): 48 return value.lower() 49 50 register.filter()也可以传递关键字参数: is_safe, needs_autoescape, and expects_localtime 51 52 建议写法: 53 from django import template 54 from django.template.defaultfilters import stringfilter 55 register = template.Library() 56 57 @register.filter 58 @stringfilter # 传递参数为数字时,不会报AttributeError异常 59 def lower(value): 60 return value.lower() 61 62 模板中filter调用格式: 63 {{ first_param|custom_filter second_param }} 64 65 66 二、自定义template tags 67 tags比filter复杂,因为tags可以做任何事情。 68 django.template.Library.simple_tag() 69 70 1. simple_tag 函数可以接受任意数量的位置、关键字参数 71 @register.simple_tag 72 def my_tag(a, b, *args, **kwargs): 73 warning = kwargs['warning'] 74 profile = kwargs['profile'] 75 ... 76 return ... 77 78 2. 修改tag名字 79 register.simple_tag(lambda x: x - 1, name='minusone') 80 81 @register.simple_tag(name='minustwo') 82 def some_function(value): 83 return value - 2 84 85 3.模板中使用tags 86 {% custom_tag params %} 或者 {% custom_tag params as result%} {{result}} 87 88 注意:tags 可以和 filter一起使用。{% my_tag 123 "HelloWorld" warning="MESSAGE"|lower profile=user.profile %} #lower为上面定义的filter 89 90 91 92 三、inclusion tags 93 django.template.Library.inclusion_tag() 94 另外一种常用模板标签是通过render另外一个模板展示一些数据。比如:django admin后台使用自定义tag沿着'add/change'底部展示按钮 95 96 97 98 99 参考: https://docs.djangoproject.com/en/2.2/howto/custom-template-tags/
learn a little every day