admin

Django笔记
DjangoDjango是一个开放源代码的Web应用框架,由Python写成。Django的MTV模式本质上和MV...
扫描右侧二维码阅读全文
01
2019/03

Django笔记

Django

Django是一个开放源代码的Web应用框架,由Python写成。

Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:
M 代表模型(Model):负责业务对象和数据库的关系映射(ORM)。
`T 代表模板 (Template)`:负责如何把页面展示给用户(html)。
`V 代表视图(View)`:负责业务逻辑,并在适当时候调用Model和Template。

安装

pip install Django==2.1.1

创建项目:

django-admin startproject 项目名

目录说明:

|-- HelloWorld
|   |-- __init__.py
|   |-- settings.py
|   |-- urls.py
|   `-- wsgi.py
`-- manage.py
  • HelloWorld: 项目的容器。
  • manage.py: 一个实用的命令行工具,可让你以各种方式与该 Django 项目进行交互。
  • HelloWorld/__init__.py: 一个空文件,告诉 Python 该目录是一个 Python 包。
  • HelloWorld/settings.py: 该 Django 项目的设置/配置。
  • HelloWorld/urls.py: 该 Django 项目的 URL 声明; 一份由 Django 驱动的网站"目录"。
  • HelloWorld/wsgi.py: 一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目。

启动服务器

python manage.py runserver 0.0.0.0:8000

函数与语法

url() 可以接收四个参数,分别是两个必选参数:regex、view 和两个可选参数:kwargs、name

  • regex 正则表达式,与之匹配的 URL 会执行对应的第二个参数 view
  • view 用于执行与正则表达式相匹配的URL请求
  • kwags 视图使用的字典类型的参数
  • name 用来反向获取 URL

django模板引擎使用{{变量}}{%代码段%}表示方法

ifequal和ifnotequal标签
{% ifequal %} 标签比较两个值,当他们相等时,显示在 {% ifequal %}{% endifequal %} 之中所有的值。而且都支持可选的分支语句{%else%}

注释标签:

{#注释#}

include标签
{% include %} 标签允许在模板中包含其它的模板的内容。

过滤器:

模板过滤器可以在变量被显示前修改它,过滤器使用管道字符,如下所示:

{{ name|lower }}

有些过滤器有参数。 过滤器的参数跟随冒号之后并且总是以双引号包含。 例如:

{{ name|truncatewords:"30" }}

表示显示变量name的前30个字符
其他过滤器:

  • adslashes : 添加反斜杠到任何反斜杠、单引号或者双引号前面。
  • date : 按指定的格式字符串参数格式化 date 或者 datetime 对象,实例:
pub_date|date:"F j, Y" }}
  • length : 返回变量的长度。

自定义过滤器

  1. 再app中创建templatetags模块
  2. 创建任意py文件

Django要求我们自定义的过滤器必须要在django中进行注册所以必须导入以下两列语句

from django import template

register = template.Library()

#定义过滤器
@register.filter
def filter_multi(v1,v2):
    
    return v1*v2

#定义标签

@register.simple_tag
def simple_tag_multi(v1, v2):

    return v1 * v2

  1. 在使用自定义filtersimple_tag的html文件中导入之前创建的my_tag.py文件
{% load my_tag %}
  1. 使用simple_tagfilter
-------------模板页面.html--------------------

{% load my_tags %}  
      
# num=12
{{ num|filter_multi:2 }} #24   #参数只能有一个
 
{{ num|filter_multi:"[22,333,4444]" }}
 
{% simple_tag_multi 2 5 %}  #参数不限,但不能放在if for语句中
{% simple_tag_multi num 5 %}

注意

  • filter可以用于if语句之后而simple_tag不可以
  • 过滤器: {{var|filter_name:参数}} # 参数只能是一个
  • 标签: {% simple_tag 参数1 参数2 ... %} #参数不限

模板继承
模板可以用继承的方式来实现复用。
{%extents "父级模板"%}
在模板继承中可以使用 {% block %} 标签告诉模板引擎,子模板可以重载这些部分。
例如:
父级模板:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>base</title>
</head>
<body>
    <p>Hello django</p>
   {% block mainbody %}
       <p>这是继承的内容<p>
    {% endblock %}

</body>
</html>

子级模板:


{% extends "base.html" %}
{% block mainbody %}
    <p>test:{{time}}</p>{# 这是重载的部分#}
{% endblock %}

HTTP请求

HttpRequest:
HttpRequest对象是一个包含发送HTTP请求内容的对象含有很多属性

  • HttpRequest.scheme 返回发送请求的协议是http或者https
  • HttpRequest.method 返回请求方式是GET或者POST
  • HttpRequest.path 返回请求页面的完整路径不包含域名和端口
  • HttpRequest.body
  • HttpRequest.path_info 返回除WSGIScriptAlias设置的路径外的完整路径 例如:如果设置 www.a.com/a/ 为根目录,如果访问 www.a.com/a/b/ path输出为a/b/ path_info 输出为'/b
  • HttpRequest.encoding 表示用于解码表单提交数据的当前编码的字符串(如果为None表示使用的 DEFAULT_CHARSET)
  • HttpRequest.content_type 表示请求的MIME类型的字符串,从CONTENT_TYPE标头解析
  • HttpRequest.content_params 表示请求的参数形式为字典类型
  • HttpRequest.COOKIES 返回一个字典,包含浏览器存储的所有cookie
  • HttpRequest.FILES 返回一个MultiValueDict,包含上传的文件
  • HttpRequest.META 返回一个包含所有请求相关信息的字典(包含Headers),同environ
CONTENT_LENGTH -- The length of the request body (as a string).
CONTENT_TYPE -- The MIME type of the request body.
HTTP_ACCEPT -- Acceptable content types for the response.
HTTP_ACCEPT_ENCODING -- Acceptable encodings for the response.
HTTP_ACCEPT_LANGUAGE -- Acceptable languages for the response.
HTTP_HOST -- The HTTP Host header sent by the client.
HTTP_REFERER -- The referring page, if any.
HTTP_USER_AGENT -- The client's user-agent string.
QUERY_STRING -- The query string, as a single (unparsed) string.
REMOTE_ADDR -- The IP address of the client.
REMOTE_HOST -- The hostname of the client.
REMOTE_USER -- The user authenticated by the Web server, if any.
REQUEST_METHOD -- A string such as "GET" or "POST".
SERVER_NAME -- The hostname of the server.
SERVER_PORT -- The port of the server (as a string).
  • HttpRequest.resolver_match 返回请求处理的url及相关参数
  • HttpRequest.session 返回中间件 session,一个可读可写的字典对象
  • HttpRequest.GET/POST 返回get/post请求的数据

方法:

  • HttpRequest.get_host() 获取请求的主机和端口
  • HttpRequest.get_port() 获取端口
  • HttpRequest.get_full_path()返回完整路径同path
  • HttpRequest.is_ajax() 判断是否为ajax请求
  • HttpRequest.is_secure() 判断是否为https请求
  • HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)返回已签名cookie的cookie值,如果签名不再有效,则引发django.core.signing.BadSignature异常.如果提供默认参数,则将禁止该异常,并返回该默认值。

HttpResponse
对请求返回的数据包
属性:

  • content:表示返回的内容,字符串类型
  • charset:表示response采用的编码字符集,字符串类型
  • status_code:响应的HTTP响应状态码
  • content-type:指定输出的MIME类型

方法

  • init :使用页内容实例化HttpResponse对象
  • write(content):以文件的方式写
  • flush():以文件的方式输出缓存区
  • set_cookie(key, value='', max_age=None, expires=None):设置Cookie
key、value都是字符串类型
max_age是一个整数,表示在指定秒数后过期
expires是一个datetime或timedelta对象,会话将在这个指定的日期/时间过期,注意datetime和- timedelta值只有在使用PickleSerializer时才可序列化
max_age与expires二选一
如果不指定过期时间,则两个星期后过期

简写函数:

  • render(request, template_name[, context]) 结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的HttpResponse对象
request:该request用于生成response
template_name:要使用的模板的完整名称
context:添加到模板上下文的一个字典,视图将在渲染模板之前调用它
  • redirect(to) 重定向

ORM

ORM:Object Relational Mapping(关系对象映射)

类名——> 数据库中的表名

类属性——>数据库里的字段

类实例——>数据库表里的一行数据

Django orm的优势:

django的orm操作本质是根据所对接的数据库引擎,翻译成相应的sql语句。所有Django开发的项目无需关心程序底层使用的是哪种的数据库。

  1. 在使用Model时需要在setting.py文件中添加app名字 python manage.py startapp appname

mark

  1. 在templatetags—>models.py 创建类实例
from django.db import models

# Create your models here.

class Book(models.Model):
    name = models.CharField(max_length=20)
    price = models.FloatField()
    pub_date = models.DateField()
    author = models.CharField(max_length=32,null=False)

class author(models.Model):
    name = models.CharField(max_length=32)

  1. 在shell终端中执行 python manage.py makemigrations 后会在migrations文件夹下生成xxx_initial.py文件
# Generated by Django 2.1.1 on 2018-09-09 02:34

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Book',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=20)),
                ('price', models.FloatField()),
                ('pub_date', models.DateField()),
            ],
        ),
    ]
  1. 执行python manage.py migrate 会根据model生成相应的sql并在数据库中建立相应的表

mark

使用其他数据库需要在settings.py中更改DATABASE{}中的代码,例如mysql

DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql', #数据引擎
    'NAME':'day70', #数据库名
    'USER': 'eric', #数据库用户名
    'PASSWORD': '123123', #数据库密码
    'HOST': '192.168.182.128',#数据库ip
    'PORT': '3306', #数据库端口号
    }
}

如果需要观察sql语句执行的记录需要在settings.py中添加LOGGING扩展

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

Database API:

  1. 创建一个类的实例
  2. 在实例对象中使用save()方法

    b = Book(name='shuihu',price=12)
    b.save()

第二种方式(create):

在每一个Django的model都至少有一个Manager,默认有一个Manager叫objects(即objectsdjango.db.models.manager.Manager的实例)

创建一个对象:

Book.objects.create(name='shuihu',price=20)

查询:

  1. all() 获得所有的对象
  2. filter() 过滤器 返回满足条件的对象集合
  3. exclude() 在所有对象的集合中排除满足条件的对象集合并返回
  4. get() 获得某一个对象

在查询操作中可以使用列表中的切片

查找条件:

QuerySet集合对象的特性:

惰性机制:

xxx.objects.all()或者xxx.objects.filter()都只是返回了一个QuerySet对象,并不会立刻执行sql语句,而是当调用此QuerySet的时候才会执行

特点:

  • 可迭代的
  • 可切片

高效使用:

  • QuerySet是具有缓存的当遍历这个几何对象时,所有匹配的记录会从数据库中获取,然后转换为Django的model。这些model会保存在queryset内置的cache中。重复查询时则会从cache中获取而不是再次执行从数据库中获取

Views

Models

基础概念

模型包含着储存数据的重要字段和行为,一般来说每一个模型都映射着一个数据库表

  1. 每一个模型都是一个Python类,都继承与django.db.models.Model
  2. 模型的每个属性都是一个数据库的字段
models中的数据类型
AutoField IntegerField
BooleanFieldtrue/false
CharFieldmaxlength,必填
TextField
CommaSeparatedIntegerFieldmaxlength,必填逗号分隔
DateFieldauto_now可选,每次动作都会更新auto_now _add可选,一次产生
DateTimeFieldauto_now可选,每次动作都会更新auto_now _add可选,一次产生
EmailField
FileFieldupload_to,可选object.get_myfile_url
FilePathFieldpath必填"/home/images"match可选,正则表达式,用于过滤文件名recursive可选,False,表示path的子目录是否包含在内
FloatFieldmax_digits必填,数字长度decimal_places必填,即有效位数
ImageFieldupload_to height_field可选width_field可选需要验证,即Python Imaging Library
IntegerField
IPAddressField
NullBooleanField 相当于设置了null=True的BooleanField
PhoneNumberField 美国电话号码格式
PositiveIntegerField 正整数字段
PositiveSmallIntegerField 小的正整数字段,取决于数据库特性
SlugFieldmaxlength(50)可选db_index默认为Trueprepopulate_from可选,用于指示在admin表单中的可选值短标签,仅包含字母、数字、下划线、连字符,一般用于url
SmallIntegerField 小整数字段,依赖于数据库特性
TimeFieldauto_now可选,每次动作都会更新auto_now _add可选,一次产生
URLFieldverify_exists(True),检查URL可用性
USStateField 两个字母表示的美国州名字段
XMLFieldschema_path,必选
字段选项

任何一个字段类型都可接受一个可选参数verbose_name设置备注名。如果未指定该参数值, Django 会自动使用该字段的属性名作为该参数值,并且把下划线转换为空格

  • null 如果这设置为True,当字段为空时,Django会将数据库中该字段设置为NULL,默认为False
  • blank 如果设置为True ,该字段允许为空,默认False
  • choices 该参数接收一个可迭代的列表或元组(基本单位为二元组)。如果指定了该参数,在实例化该模型时,该字段只能取选项列表中的值。
  • default 该字段的默认值。可以是一个值或者是个可调用的对象,如果是个可调用对象,每次实例化模型时都会调用该对象
  • help_text帮助文本
  • primary_key 如果设置为True则将该字段设置为该模型的主键
  • unique 如果设置为True则此字段在表中必须是唯一的
关联关系

Django提供了定义三种最常见的数据库关联关系的方法:

  • 一对一
  • 多对多
  • 多对一
from django.db import models

class Publisher(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()

class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=40)
    email = models.EmailField()

class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()

多对一(ForeignKey):

假如一个Book模型有一个出版社Publisher,也就是说一个Publisher可以出版很多本书,但是每个Book只对应一个Publish

class Book(models.Model):
title = models.CharField(max_length=100)
publisher = models.ForeignKey(Publisher)

多对多(ManytoManyField):

一个Book可以有多个作者Author,也就是说一个Author可以写多个Book

class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()

Admin

注册

在admin.py中只需要讲Mode中的某个类注册,即可在Admin中实现增删改查的功能

admin.site.register(models.UserInfo)

但是,这种方式比较简单,如果想要进行更多的定制操作,需要利用ModelAdmin进行操作,如:

方式一:
    class UserAdmin(admin.ModelAdmin):
        list_display = ('user', 'pwd',)
 
    admin.site.register(models.UserInfo, UserAdmin) # 第一个参数可以是列表
     
 
方式二:
    @admin.register(models.UserInfo)                # 第一个参数可以是列表
    class UserAdmin(admin.ModelAdmin):
        list_display = ('user', 'pwd',)

ModelAdmin中提供了大量的定制功能

问题:

'WSGIRequest' object has no attribute 'user'

官方文档:

https://docs.djangoproject.com/en/2.0/topics/http/middleware/#activating-middleware

在使用django-admin startproject 会默认在settings.py中生产:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

而且AuthenticationMiddleware讲经过验证的用户存储到session中,所以必须要在SessionMiddleware后运行

Django 请求流程

Last modification:August 20th, 2019 at 05:36 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment