Django

Pycharm 小技巧

form>input*3 #tab直接自动补全
div>div.page*3 #3个div class=page

Models

class BookInfo(models.Model):
    '''id 会默认存在不需要自己添加 使用pk取id的值'''
    STATUS_CHOICES = (
        (0, 'ADD'),
        (1, 'Ending'),
        (2, 'Unreachable')
    )
    name = models.CharField(max_length=10)
    finger = models.JSONField(null=True, verbose_name='指纹')
    status = models.IntegerField(choices=STATUS_CHOICES, default=0, verbose_name='扫描状态')
    add_time = models.DateTimeField((default=datetime.now, blank=True, verbose_name='添加时间')  # 格式:2022-02-11 15:27:28
    class Meta:
    	db_table = 'bookinfo'  # 数据库表名前就不会有默认的appName了
    	verbose_name = 'admin'  # admin后台显示信息
    	
class Store(models.Model):
    name = models.ForeignKey(Jobs, on_delete=models.CASCADE, related_name='store', verbose_name='店铺')
    icp = models.CharField(max_length=256, verbose_name='备案', default='无')

    class Meta:
        db_table = 'fp_store'
        verbose_name = '店铺'

# 使用Django提供的User模型
class User(AbstractUser):
    mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')

    class Meta:
        db_table = 'fp_users'
        verbose_name = '用户'
        verbose_name_plural = verbose_name

views

    request
    	request.method == 'POST'
    	jid = request.POST.get('id')
    	queryset = Jobs.objects.get(pk=jid)
    	requset.path #当前请求路径
    Response
    	HttpResponse(<h1>Test<h1>)
    	render(request,'index.html',{'name':'abc'})
    	render_to_response('index.html',{'name':'abc'})
    	render_to_response('index.html',locals) #前端可以用本地变量
    	redirect() #重定向
    	JsonResponse() # 返回json数据

settings配置


    # CORS 跨域等操作
    ALLOWED_HOSTS = ['*']
    X_FRAME_OPTIONS = 'SAMEORIGIN'

    # 模版TEMPLATES配置
    'DIRS': [os.path.join(BASE_DIR, 'templates')] #模板文件路径
    
    # 时区/语言等
    LANGUAGE_CODE = 'zh-hans'
    TIME_ZONE = 'Asia/Shanghai'
    USE_I18N = True
    USE_L10N = True
    USE_TZ = False
    
    # 静态文件配置
    STATIC_URL = '/static/' #引用名  可以随便替换静态文件路径 同样可以访问到
    STATIC_ROOT = os.path.join(BASE_DIR, 'static')
    STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_root')] ##实际名 即实际静态文件夹的名字
    
    # Mysql 配置
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '127.0.0.1',
            'PORT': 3306,
            'USER': 'fingerprint',
            'PASSWORD': 'fingerprint',
            'NAME': 'fingerprint',
            'OPTIONS': {'charset': 'utf8mb4'}  # 字符集为utf8mb4
        }
    }

    # django 用户模型
    AUTH_USER_MODEL = 'users.User'

    # 工程日志
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,  # 是否禁用已经存在的日志器
        'formatters': {  # 日志信息显示的格式
            'verbose': {
                'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
            },
            'simple': {
                'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
            },
        },
        'handlers': {  # 日志处理方法
            'console': {  # 向终端中输出日志
                'level': 'INFO',
                'class': 'logging.StreamHandler',
                'formatter': 'simple'
            },
            'file': {  # 向文件中输出日志
                'level': 'INFO',
                'class': 'logging.handlers.RotatingFileHandler',
                'filename': os.path.join(os.path.dirname(BASE_DIR), 'logs/Fingerprint.log'),  # 日志文件的位置
                'maxBytes': 300 * 1024 * 1024,
                'backupCount': 10,
                'formatter': 'verbose'
            },
        },
        'loggers': {  # 日志器
            'django': {  # 定义了一个名为django的日志器
                'handlers': ['console', 'file'],  # 可以同时向终端与文件中输出日志
                'propagate': True,  # 是否继续传递日志信息
                'level': 'INFO',  # 日志器接收的最低日志级别
            },
        }
    }

urls 路由(路径映射)配置

从上到下的顺序匹配
最好在某一个功能或者一个模块下新建一个urls.py 在全局中做指派
# Import the include() function: from django.urls import include, path
# Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
urlpatterns = [
    path(正则表达式, views视图函数,参数,别名),
    path(r'^articles/2003/$', views.articles_2003),
    path(r'^articles/([0-9]{4})/$', views.articles_year),  #即([0-9]{})匹配到的结果会传递给视图函数 视图函数接收的顺序时固定的
    path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.article_detail), #匹配结果起名分组 视图函数使用分组名接收 没有顺序限制 
    path(r'^articles/$', views.articles, {'year':'2003'}), #向视图函数传递year参数
    path(r'^articles/$', views.articles, name = 'art'), #别名, 替换articles路径为art 使用别名时 模板路径写法 {% url 'art' %}
    re_path('static/(?P<path>.*)$', static.serve, {'document_root': dev.STATIC_ROOT}) # 解决关闭debug静态文件问题
]
参数说明:
一个正则表达式字符串 
一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
可选的要传递给视图函数的默认参数(字典形式)
一个可选的name参数

TEMPLATES 默认模板

{{ 变量 }}
    万能句点"."
    	{{ obj.N }} #取列表中某一个元素
    	{{ obj.info }} #取字典中键所对应的值
    	#对象的内容也可以通过.取
{%  %}
    {% if True%} 
    语句块
    {% endif %}

    {% for i in obj%} 
    {{ i }}
    {% endfor %}

filter
    格式: 变量|过滤器:参数
    {{ value|upper }} #将value大写
    {{ value|lower }} #将value小写
*	{{ value|addslashes }} #转义
    {{ value|first }} #value首字
    {{ value|capfirst }} #将value首字母大写
    {{ value|add:5 }} #value + 5 
    {{ value|cut:' ' }} #将value中的空格去掉
*	{{ value|date:'Y年-m月-d日' }} #将value中时间格式
*	{{ value|default:'空' }} #当value为空时显示空
*	{{ value|safe }} #当value为html代码时后加safe才可以被渲染 效果同autoescape off
    {{ value|filesizeformat }} #value所占的大小
    {{ value|length }} #value的长度
    {{ value|slice: ':-1' }} #value的值做切片
    {{ value|urlencode }} #当value为url时对value编码
    {{ value|truncatechars:'6' }} #对value的值进行按字符截
    {{ value|truncatewords:'2' }} #对value的值进行按词截
simple_tag
    #在app下templatetages文件下找
    需要引入的模块
    	from django import template
    	from django.utils.safestring import mark_safe
    调用装饰器
    	register = template.Library()   #register的名字是固定的,不可改变

    	@register.simple_tag   #可以加多个参数但是不可以跟在if后
    	def xxx(v1,v2,v3,v4):  #在模板中调用方式先load templatetages下创建好的文件{% load xxx.py %} {% my_add 1 2 3 4 %}
    		return v1 + v2 + v3 + v4
simple_filter
    	@register.filter   #参数不能超过两个 value是第一个参数 8是第二个参数
    	def add100(v1,v2): #在模板中调用方式 {{value|add100:8}}
    		return v1 + 100 +v2
    	}

autoescape
    {% autoescape off %}
    	{{ value }}      #当value为html代码时放在autoescape off中才会被渲染
    {% endautoescape %}
CSRF
    {% csrf_token %} #form表单中添加就不会出现csrf问题了
url
    {% url 'art' %} #别名
with
    {% with name=zhangsan %} #将传递过来的变量名zhangsan替换为name
    {{name}} 
    {% endwith %}
verbatim
    {% verbatim %}
    {{ name }}    #页面上将会显示{{ name }} 不会进行渲染
    {% endverbatim %}

    母版
    	放公共的部分
    	{% block content %}

    	{% endblock %}
    	{% block content2 %}

    	{% endblock %}

    继承母版
    	{% extends 'base.html' %}
    	{% block content %} #当母版block中有内容时会进行覆盖
    		html语句        # 如果使用{{ block.super }}时会继承母版block中内容
    	{% endblock %}

jinjia2模版

settings设置BACKEND为 `'django.template.backends.jinja2.Jinja2'`配置Jinja2引擎。

过滤器

{{ data(value) }}
# loopfor 替换为了 loop
# loop.index 从1开始
# loop.index0 从0开始
  1. 常用过滤器
过滤器 说明
safe 渲染是不转义
capitalize 首字母大写
lower 所有字母小写
upper 所有字母大写
title 值中每个单词首字母大写
trim 删除首位空白字符
striptags 渲染时删除掉值中所有HTML标签

注意:safe过滤器,默认情况下,处于安全考虑,Jinja2会转义所有变量,例如一个变量的值为 <h1>Hello</h1>, Jinja2会将其渲染成 &lt;h1&gt;Hello&lt;/&gt;,浏览器会显示出原本的值,但是不会解释。如果需要浏览器解释的话,可以使用 safe 过滤器 例如模板文件 html.html为:

<h1>
{{ html | safe }}
</h1>
  1. 自定义过滤器

自定义过滤器需要在settingsTEMPLATES中加入 'environment': 'ProjectName.utils.jinja2_env.jinja2_environment' 注册后在模版中使用

from django.contrib.staticfiles.storage import staticfiles_storage
from django.urls import reverse
from jinja2 import Environment


def jinja2_environment(**options):
    """jinja2环境"""

    # 创建环境对象
    env = Environment(**options)

    # 自定义语法 {{ static('静态文件相对路径') }} ,{{ url('路由的命名空间') }}
    env.globals.update({
        'static': staticfiles_storage.url,
        'url': reverse,
    })
    env.filters.update({
        'jobStatus': jobStatus,
    })
    # 返回环境对象
    return env

def jobStatus(value):
    return eval('value.get_status_display()')  # apply(eval('value.get_'+arg+'_display'), ())

html

{{ value|jobStatus() }}

ORM 数据库操作

单表

# 方法一
UserInfo.objects.create(userName = userName)

# 方法二
UserInfo.objects.create(**{'userName': userName})

# 方法三
info = UserInfo(userName = userName)
info.save()

# 方法四
info = UserInfo()
info.userName = userName
info.save()

models.UserInfo.objects.filter(userName=userName).delete()

# 方法一
info = UserInfo.objects.get(userName = userName)  # 拿到的是userName = userName的一个对象
info.email = '123@qq.com'
info.save()

# 方法二
UserInfo.objects.filter(userName = userName).update(email='22222222@qq.com')  # 拿到的是集合 会将所有userName = userName拿到的数据修改掉

# filter
UserInfo.objects.filter(userName = userName)[0]

# all
UserInfo.objects.all()

# get
UserInfo.objects.get(userName = userName)[0]
# 对查询结果的处理 filter\all\get	

# exclude
UserInfo.objects.get(userName = '张三')
# 查询不包含张三的用户

# values
UserInfo.objects.filter(userName = userName).values('email')

# order_by
UserInfo.objects.order_by("-userName") #-为倒序

# reverse
UserInfo.objects.reverse("userName")  #对结果反向排序

# 结果取反
UserInfo.objects.reverse(~Q(userName=''))  #对结果反向排序

distinct #取除重复项
count    #返回匹配到的对象数量
exists   #判断数据是否存在
models.UserInfo.objects.filter(userName=userName).exists()

# Q查询
__exact 精确等于      like 'aaa'
__iexact 精确等于    忽略大小写 ilike 'aaa'
__contains 包含 like '%aaa%'
__icontains 包含        忽略大小写 ilike '%aaa%',
__gt 大于
__gte 大于等于
__lt 小于
__lte 小于等于
__in 存在于一个list范围内
__startswith 以...开头
__istartswith 以...开头 忽略大小写
__endswith 以...结尾
__iendswith 以...结尾,忽略大小写
__range 在...范围内
__year 日期字段的年份
__month 日期字段的月份
__day 日期字段的日
__isnull=True/False

# F查询
# 两个属性进行比较时使用
filter(字段名__运算符=F('字典名'))

关联表

# 一对一
models.OneToOne('')

# 一对多
# 在多的里面绑定
models.ForeignKey('')

# 多对多
# 在哪个绑定都可以
models.ManyToManyField('')  # 会出现第三张表

# 关联查询
# 已知主表数据 关联查询从表数据
# 主表模型(实例对象).关联模型累名小写_set.all()
book = BookInfo.objects.get(id=1)  #  查询id为1的书
book.peopleinfo_set.all()  # 查询数据关联的人物
filter(外键__字段__运算符=值)
PeopleInfo.object.filter(book__name='阿Q正传')

# 已知从表数据 关联查询主表数据
# 从表模型(实例对象).外键
PeopleInfo.book
filter(关联模型类名小写__字段__运算符=值)
BookInfo.object.filter(peopleinfo__name=''阿Q')  # 查找人名为张三的书

文章作者: 子杰
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 子杰 ! !
评论
 上一篇
使用Python 给AWVS13 批量添加任务 使用Python 给AWVS13 批量添加任务
使用Python 给AWVS13 批量添加任务由于在awvs13中批量导入csv格式任务出现问题,所以有了此脚本 配置 将apikey替换为自己的 将需要扫描的url放入到脚本同一目录下的url.tx
2020-05-18
下一篇 
爬虫相关 爬虫相关
网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的U
2022-03-03
  目录