1.中介模型

中介模型,这个是在我们创建表格时,多对多添加的时候应用到的,通过制定ManyToManyField字段中的through参数来定义,为两者的关系新建一个中介class

为什么会产生这个中介模型呢?主要还是和业务需求有关系:

我们都知道,建立多对多关系后,django会自动帮我们生成第三张表,对于这张表只包含相关的id。但是由于业务需要,我们现在需要在第三张表添加其它字段,这时候就需要自己去创建第三张表

1.1用法实例

常规多对多创建表模型:

class Author(models.Model):
name = models.CharField(max_length=32) class Book(models.Model):
title = models.CharField(max_length=32)
authors = models.ManyToManyField(to='Author')  

效果:

中介模型:

class Author(models.Model):
name = models.CharField(max_length=32) class Book(models.Model):
title = models.CharField(max_length=32)
authors = models.ManyToManyField(to='Author', through='Book2Author') class Book2Author(models.Model):
book_id = models.ForeignKey(to='Book',on_delete=models.CASCADE)
author_id = models.ForeignKey(to='Author',on_delete=models.CASCADE)
place = models.CharField(max_length=32)
class Meta:
unique_together = [("book_id", "author_id")]

效果:

# 注意:中介模型没有add,areate,remove方法,但是clear() 方法却是可用的。它可以清空某个实例所有的多对多关系

2.CBV模式说明

相应的还有FBV(funvcion base view)模式,FBV(function base views) 就是在视图里使用函数处理请求

CBV的实现是django中把之前的视图函数通过类来实现

CBV定义一定要继承django.views.View

注册路由的时候要写类名.as_view()

具体原理是dispatch()方法中利用反射找到每个请求要执行的方法

2.1用法实例(如果还不明白,可以点击源码查看相关属性介绍)

urls.py

注意:这里的Login_cbv是类名,它必须后面调用as_view()
url(r'^login_cbv/$', views.Login_cbv.as_view())

views.py

from django.views import View
class Login_cbv(View):
def get(self,request): #如果是get请求需要执行的代码
return render(request,"login_cbv.html")
def post(self,request): #如果是post请求需要执行的代码
return HttpResponse(".....")
def delete(self,request):
pass

login_cbv.html

<form action="/login_cbv/" method="post">
{% csrf_token %}
姓名:<input type="text">
<input type="submit">
</form>

# 在源码说明中,可以看见总共有八种请求方式

http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

部分请求协议说明:

GET      :从服务器取出资源(一项或多项)

POST    :在服务器新建一个资源

PUT      :在服务器更新资源(客户端提供改变后的完整资源)

PATCH  :在服务器更新资源(客户端提供改变的属性)

DELETE :从服务器删除资源

3.LOGGING日志

写Django项目常用的logging配置,在django的setting文件下配置如下代码:

BASE_LOG_DIR = os.path.join(BASE_DIR, 'log')
# 日志相关配置
LOGGING = {
'version': 1, # 保留字段
'disable_existing_loggers': False, # 不要禁用已经存在的logger实例 'formatters': { # 定义三种日志显示的格式
'standard': {
'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]'
'[%(levelname)s][%(message)s]'
},
'simple': {
'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
},
'collect': {
'format': '%(message)s'
}
}, 'filters': { # 定义一个过滤规则
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
}, 'handlers': { # 日志流的处理方式
'console': { # 把日志打印到终端
'level': 'DEBUG',
'filters': ['require_debug_true'], # 只有在Django debug为True时才在屏幕打印日志
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'default': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切
'filename': os.path.join(BASE_LOG_DIR, "info.log"), # 日志文件
'maxBytes': 1024 * 1024 * 500, # 日志大小 500M
'backupCount': 3, #
'formatter': 'standard',
'encoding': 'utf-8',
},
'error': {
'level': 'ERROR',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切
'filename': os.path.join(BASE_LOG_DIR, "err.log"), # 日志文件
'maxBytes': 1024 * 1024 * 500, # 日志大小 500M
'backupCount': 5,
'formatter': 'standard',
'encoding': 'utf-8',
},
'collect': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切
'filename': os.path.join(BASE_LOG_DIR, "collect.log"),
'maxBytes': 1024 * 1024 * 500, # 日志大小 500M
'backupCount': 5,
'formatter': 'collect',
'encoding': "utf-8"
}
},
'loggers': { # 默认的logger应用如下配置
'': {
'handlers': ['default', 'console', 'error'], # 上线之后可以把'console'移除
'level': 'DEBUG',
'propagate': True, # 是否向父级logger实例传递日志信息
}, # 名为 'collect'的logger还单独处理
'collect': {
'handlers': ['console', 'collect'],
'level': 'INFO',
}
},
} INTERNAL_IPS = ['127.0.0.1', ]
DEBUG_TOOLBAR_CONFIG = {
"JQUERY_URL": '//cdn.bootcss.com/jquery/2.2.4/jquery.min.js',
}

# 用法:

在需要的文件中引入

import logging

loger = logging.getLoggr(__name__)  # 生成一个以当前文件名为名字的 logger实例

在需要的位置下引入即可

示例:

def get(self, request, name):
res = {"code": 0}
# 拿到第一个学校对象
school_obj = models.School.objects.filter(name=name).first()
if not school_obj:
logger.warning('找不到学校信息...')
collect_logger.info(name) logger.debug('我来获取名字为{}学校详情'.format(name))
logger.info('我来获取名字为{}学校详情'.format(name))

4.django-debug-toolbar

一组可配置的面板,可显示有关当前请求/响应的各种调试信息,并在单击时显示有关面板内容的更多详细信息。文档地址猛戳这里

4.1 安装模块

pip3 install django-debug-toolbar

4.2 setting配制

settings.py中将 debug_toolbar 添加到 INSTALL_APPS 中

INSTALLED_APPS = [

'debug_toolbar',
]

4.3 urls.py中

from django.conf import settings
from django.conf.urls import include, url if settings.DEBUG:
import debug_toolbar
urlpatterns = [
url(r'^__debug__/', include(debug_toolbar.urls)),
] + urlpatterns

4.4 settings.py中在中间件中加入DebugToolbarMiddleware

MIDDLEWARE = [
# ...
'debug_toolbar.middleware.DebugToolbarMiddleware',
# ...
]

4.5 如果是本机调试,还在将127.0.0.1加入 INTERNAL_IPS,在settings.py中加入以下配置项:

INTERNAL_IPS = ['127.0.0.1', ]

4.6 配置jQuery的URL

django-debug-toolbar 默认使用的是Google的地址,默认配置如下:

JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js'

国内用不了的话可以在settings.py中配置一下,例如(我这里特意选用了和原作者相同版本的jQuery):

DEBUG_TOOLBAR_CONFIG = {
"JQUERY_URL": '//cdn.bootcss.com/jquery/2.2.4/jquery.min.js',
}

# 或者你如果在Django项目中使用了jquery的话就可以直接将这一项置为空,即 "JQUERY_URL": ' ',那么django-debug-toolbar 就会使用你项目中用到的jquery,

4.7使用效果

访问具体路径的时候在页面右侧有各项配置面板,点击即可查看各种调试信息。

 

 

django中介模型,CBV模型,及logging日志配制的更多相关文章

  1. Django之logging日志

    简介 Django使用python自带的logging 作为日志打印工具.简单介绍下logging. logging 是线程安全的,其主要由4部分组成: Logger 用户使用的直接接口,将日志传递给 ...

  2. 解决在django中应用keras模型时出现的ValueError("Tensor %s is not an element of this graph." % obj)问题

    用keras训练好模型,再在django初始化加载模型,这个过程没有问题,但是在调用到模型执行model.predict()的时候就报错: raise ValueError("Tensor ...

  3. Django 创建模型 激活模型 简单的使用模型

    创建模型: 在你的开发环境中,已经有一个“项目” —— 已经建立起来,你将开始在上面做一些东西. 你编写的每个Django应用都是一个遵循特定约定的Python包. Django自带一个工具,它可以自 ...

  4. Django学习笔记(16)——扩展Django自带User模型,实现用户注册与登录

    一,项目题目:扩展Django自带User模型,实现用户注册与登录 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册,登录,用户认证,注销,修改密码等功能. ...

  5. Django—logging日志

    简介 Django使用python自带的logging 作为日志打印工具.简单介绍下logging. logging 是线程安全的,其主要由4部分组成: Logger 用户使用的直接接口,将日志传递给 ...

  6. Django 的 logging日志文件配置

    在Django的settings配置文件里配置以下信息: import os BASE_LOG_DIR = os.path.join(BASE_DIR , "log") # log ...

  7. Django框架(七):模型(三) 关联、模型类的属性

    1. 关联 1.1 模型类关系 关系型数据库的关系包括三种类型: ForeignKey:一对多,将字段定义在多的一端中. ManyToManyField:多对多,将字段定义在任意一端中. OneToO ...

  8. Django中的CBV视图

    Web 开发是一项无聊而且单调的工作,特别是在视图功能编写方面更为显著.为了减少这种痛苦,Django植入了视图类这一功能,该功能封装了视图开发常用的代码,无须编写大量代码即可快速完成数据视图的开发, ...

  9. form,ajax注册,logging日志使用

    一.form表单类型提交注册信息 二.ajax版本提交注册信息 <!DOCTYPE html> <html lang="en"> <head> ...

随机推荐

  1. Spark机器学习库(MLlib)官方指南手册中文版

    中文https://blog.csdn.net/liulingyuan6/article/details/53582300 https://yq.aliyun.com/articles/608083 ...

  2. 浅谈jrebel

    有个同事提高个jrebel的工具,提起tomcat的热部署方案. jrebel是一款收费的JVM级的热部署工具包. JVM级的热部署也就是说,可以不重启JVM,让修改或添加的类加载到JVM中. 加载器 ...

  3. 百度 CDN公共库

    http://developer.baidu.com/wiki/index.php?title=docs/cplat/libs 简介 CDN公共库是指将常用的JS库存放在CDN节点,以方便广大开发者直 ...

  4. OpenStack Weekly Rank 2015.08.10

    Module Reviews Drafted Blueprints Completed Blueprints Filed Bugs Resolved Bugs Cinder 5 1 1 6 12 Sw ...

  5. Eclipse中引来的jar包乱码

    Eclipse中引入的jar包乱码jar包链接的源码,中文注释为乱码的解决方法: 1.将Eclipse的Preferences中的General>ContentTypes中的Java Class ...

  6. DEDECMS v5.7 完美实现导航条下拉二级菜单

    一.引言 好多人都问,织梦的下拉导航怎么做呢?其实很简单!即使你对代码一点也不熟悉,没关系! 按照我的步骤走!记住一步也不能错哦! 二.实现过程 1.首先: 将下面这段代码贴到templets\def ...

  7. JQuery 的跨域方法 可跨任意网站

    JS的跨域问题,很多人在网上找其解决方法,教其用IFRAME去解决的文章很多,真有那么复杂吗?其实很简单的,如果你用JQUERY,一个GETJSON方法就搞定了,而且是一行代码搞定. 下面开始贴出方法 ...

  8. Hibernate系列4-----之删除

    1.和它的增改查兄弟不同,多了个until包定义了HibernateUntil类,让我们来一起看看吧 public class HibernateUntil { private static Conf ...

  9. 北航oo作业第一单元小结

    前言 在经过了三次艰辛的oo作业后,oo课程的第一单元告一段落,这一单元,我作为一个oo小白,开始了解oo的编程思想,也有了自己的一点心得体会.把笔粗成字,不当之处,还请各位大佬多多指教. 一.分析程 ...

  10. JavaSE之Java基础(1)

    1.为什么重写equals还要重写hashcode 首先equals与hashcode间的关系是这样的: 1.如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相 ...