• Django


    django内容回顾

    一.创建项目基本

    1.创建项目

    django-admin.py startproject app
    

    目录说明:

    app: 项目的容器。

    manage.py: 一个实用的命令行工具,可让你以各种方式与该 Django 项目进行交互。

    python manage.py startapp appname 运行某个应用
    
    python manage.py makemigrations   用于记录数据库的所有修改
    
    python manage.py migrate          将修改的数据进行提交
    
    python manage.py createsuperuser  创建一个超级管理员
    

    app/app/__init__.py: 一个空文件,告诉 Python 该目录是一个 Python 包。

    app/app/settings.py: 该 Django 项目的设置/配置。

    增加模版路径
    
    TEMPLATE_DIRS = (
    
        os.path.join(BASE_DIR,'templates'),
    
    )
    
    用于增加静态文件路径
    
    STATICFILES_DIRS = (
    
        os.path.join(BASE_DIR,'static'),
    
    )
    

    app/templates 此目录一把自动生成并且配置好,用于放置模版

    app/static 此目录需自行创建,放置各类静态文件

    app/urls.py: 该 Django 项目的 URL 声明; 一份由 Django 驱动的网站"目录"。

    1、单一路由对应
    
    1.url(r'^index$', views.index),
    
    2、基于正则的路由   
    
    1.url(r'^index/(d*)', views.index),
    
    2.url(r'^manage/(?P<name>w*)/(?P<id>d*)', views.manage),
    
    3、添加额外的参数
    
    1.url(r'^manage/(?P<name>w*)', views.manage,{'id':333}),
    
    4、为路由映射设置名称
    
    1.url(r'^home', views.home, name='h1'),
    
    2.url(r'^index/(d*)', views.index, name='h2'),
    

    app/wsgi.py: 一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目。

    2.进入app 目录输入以下命令,启动服务器:

    python manage.py runserver 0.0.0.0:8000
    

    0.0.0.0 让其它电脑可连接到开发服务器,8000 为端口号。如果不说明,那么端口号默认为 8000。

    3.绑定 URL 与视图函数。打开 urls.py 文件

    from django.conf.urls import url
    
    from . import view
    
    urlpatterns = [
    
        url(r'^$', view.hello),
    
    ]
    

    4.在views.py中写一个视图函数以返回

    HttpResponse返回一个字符串给客户端(浏览器)

    from django.shortcuts import render,HttpResponse,redirect
    
    def hello(request):
    
        return HttpResponse("Hello world ! ")
    

    5.修改 view.py,增加一个新的对象,用于向模板提交数据:

    使用 render 来替代之前使用的 HttpResponse。render直接返回一个html文件

    PS:*****render的内部还是将html文件转换称为字符串返回给客户端

    def hello(request):
        context = 'Hello World!'
        return render(request, 'hello.html')
    模版
    <h1>Hello world !</h1>
    

    二.Django 模板标签

    使用 render 来替代之前使用的 HttpResponse。render 还使用了一个字典 context 作为参数。 context 字典中元素的键值 "hello" 对应了模板中的变量 "{{ hello }}"。

    1.直接进行位置替换

    模版
    <h1>{{ hello }}</h1>
    

    2.if/else 标签

    基本语法格式如下:
    
    模版
    {% if condition1 %}
       ... display 1
    {% elif condition2 %}
       ... display 2
    {% else %}
       ... display 3
    {% endif %}
    

    3.for 标签

    与Python的 for 语句的情形类似,{% for %} 允许我们在一个序列上迭代。
    
    <ul>
    {% for athlete in athlete_list %}
        <li>{{ athlete.name }}</li>
    {% endfor %}
    </ul>
    

    4.函数

    模板函数可以在变量被显示前修改它,函数使用管道字符,如下所示:
    {{ name|lower }} 
    
    函数的参数跟随冒号之后并且总是以双引号包含。 例如:
    {{ bio|truncatewords:"30" }}
    

    5.include 标签

    {% include %} 标签允许在模板中直接放入其它的模板的内容。
    
    {% include "nav.html" %}
    

    6.模板继承(母版)

    模板可以用继承的方式来实现复用。
    
    母版test.html
    {% block mainbody %}
       <p> text </p>
    {% endblock %}
    
    子版test2.html
    {% extends "test.html" %} #写在第一行
    
    {% block mainbody %}
    <p>继承了 test.html 文件</p>
    {% endblock %}
    

    三.Django 模型

    Django 对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。 MySQL 是 Web 应用中最常用的数据库。本章节我们将以 Mysql 作为实例进行介绍。你可以通过本站的 MySQL 教程 了解更多Mysql的基础知识。

    1.数据库配置

    settings.py: 文件代码:
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',  # 指定数据库类型
            'NAME': 'test',                        # 指定数据库
            'USER': 'test',                        # 数据库用户名
            'PASSWORD': 'test123',                 # 密码
            'HOST':'localhost',                    # 域名
            'PORT':'3306',                         # 端口
        }
    }
    
    在settings.py中找到INSTALLED_APPS这一项,如下:
    
    INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app0l',               # 添加此项
    )
    

    2.数据库

    Django规定,如果要使用模型,必须要创建一个app 目录结构如下:

    test
    |-- TestModel
    |   |-- __init__.py
    |   |-- admin.py
    |   |-- models.py
    |   |-- apps.py
    |   |-- tests.py
    |   `-- views.py
    

    django用类代表 数据库表,对象代表每一行

    常见的字段:

    AutoField(Field)
        - int自增列,必须填入参数 primary_key=True(一般会自动生成,无需手动)
    
    
    FloatField(Field)
        - 浮点型
    
    CharField(Field)
        - 字符类型
        - 必须提供max_length参数, max_length表示字符长度    
    
    TextField(Field)
        - 文本类型
    
    EmailField(CharField):
        - 字符串类型,Django Admin以及ModelForm中提供验证机制
    
    IPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
    
    DateTimeField(DateField)
        - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
    
    DateField(DateTimeCheckMixin, Field)
        - 日期格式      YYYY-MM-DD
    
    TimeField(DateTimeCheckMixin, Field)
        - 时间格式      HH:MM[:ss[.uuuuuu]]
    
    FloatField(Field)
        - 浮点型
    

    常见参数:

    null                数据库中字段是否可以为空
    default             数据库中字段的默认值
    primary_key         数据库中字段是否为主键
    db_index            数据库中字段是否可以建立索引
    unique              数据库中字段是否可以建立唯一索引
    
    blank               Admin中是否允许用户输入为空
    editable            Admin中是否可以编辑
    help_text           Admin中该字段的提示信息
    choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
    

    连表结构

    一对多:models.ForeignKey(其他表)
    多对多:models.ManyToManyField(其他表)
    一对一:models.OneToOneField(其他表)
    

    在命令行中运行实现更改:

    $ python manage.py makemigrations  # 让 Django 知道我们在我们的模型有一些变更
    $ python manage.py migrate         # 创建表结构
    

    3.数据库操作

    Django提供了多种方式来获取数据库的内容,如下代码所示:

    from django.http import HttpResponse
    
    from app01 import model
    
    # 数据库操作
    def testdb(request):
    
    
        # 通过objects这个模型管理器的all()获得所有数据行,相当于SQL中的SELECT * FROM
        list = model.Test.objects.all()
    
        # filter相当于SQL中的WHERE,可设置条件过滤结果
            放在聚合函数后则代表 having
    
        response2 = model.Test.objects.filter(id=1) 
    
        # 获取单个对象
        response3 = model.Test.objects.get(id=1) 
    
        # 限制返回的数据 相当于 SQL 中的 OFFSET 0 LIMIT 2;
        model.Test.objects.order_by('name')[0:2]
    
        #数据排序
        model.Test.objects.order_by("id")
    
        # 上面的方法可以连锁使用
        model.Test.objects.filter(name="runoob").order_by("id")
    

    更新数据

    def testdb(request):
    
        # 修改其中一个id=1的name字段
        #Test.objects.filter(id=1).update(name='Google')
    
        # 修改所有的列
        # Test.objects.all().update(name='Google')
    

    删除数据 删除数据库中的对象只需调用该对象的delete()方法即可:

    def testdb(request):
        # 删除id=1的数据
        test1 = Test.objects.get(id=1)
        test1.delete()
    
        # 另外一种方式
        # Test.objects.filter(id=1).delete()
    
        # 删除所有数据
        # Test.objects.all().delete()
    

    四.中间件

    我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下:

    也就是说,每一个请求都是先通过中间件中的process_request函数,这个函数返回 None 或者 HttpResponse 对象,如果返回前者,继续处理其它中间件,如果返回一个 HttpResponse,就处理中止,返回到网页上。假如我们通过一种技术,比如统计一分钟访问页面数,太多就把他的 IP 加入到黑名单 BLOCKED_IPS

    五.web安全

    1.CSRF(Cross-site request forgery跨站请求伪造,也被称为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。

    GET 请求不需要 CSRF 认证,POST 请求需要正确认证才能得到正确的返回结果。一般在POST表单中加入 {% csrf_token %}

    <form method="POST" action="/post-url/">
        {% csrf\_token %}
    
        <input type="text" >
    </form>
    

    如果使用Ajax调用的时候,就要麻烦一些

    $.ajax({
        type: 'POST',
        url:'URL地址',
        data: {
                username: $('#username').val(),
                content: $('#content').val(),
               'csrfmiddlewaretoken': '{{ csrf_token }}'  关键点
            },
        dataType: 'json',
        success: function(data){
    
        }
    
    })
    

    2.xss

    xss表示Cross Site Scripting(跨站脚本攻击),它与SQL注入攻击类似,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,通过插入恶意脚本,实现对用户游览器的控制。

    防范:

    # 对用户提交的内容进行关键字筛选,敏感字符不予提交
    
    # django对于直接显示的内容有自己的安全机制,只要不给提交的内容加上安全豁免  "|safe" 那么用户提交的内容会全部以字符串的形式展示
    

    六.Cookie

    简单定义:保存在客户端的特殊键值对.

    程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。

    1.设置Cookie:

    rep = HttpResponse(...) 或 rep = render(request, ...)
    
    rep.set_cookie(key,value,...)
    rep.set_signed_cookie(key,value,salt='加密盐',...)
          --参数:
                key,              键
                value='',         值
                max_age=None,     超时时间
                path='/',         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
                domain=None,      Cookie生效的域名
                secure=False,     https传输
                httponly=False    只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
    

    2.获取Cookie:

    request.COOKIES['key']
    request.COOKIES.get("key",default=None),取不到默认为Null
    
    request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    
          --参数:
                default: 默认值
                   salt: 加密盐
    

    七.session

    Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。

    Django中默认支持Session,其内部提供了5种类型的Session供开发者使用:

    • 数据库(默认)

    • 缓存

    • 文件

    • 缓存+数据库

    • 加密cookie

    1.配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认为数据库)
    
    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
    SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
    

    2.使用

    def index(request):
        # 获取、设置、删除Session中数据
        request.session['k1']
        request.session.get('k1',None)
        request.session['k1'] = 123
        request.session.setdefault('k1',123) # 存在则不设置
        del request.session['k1']
    
        # 所有 键、值、键值对
        request.session.keys()
        request.session.values()
        request.session.items()
        request.session.iterkeys()
        request.session.itervalues()
        request.session.iteritems()
    
    
        # 用户session的随机字符串
        request.session.session_key
    
        # 将所有Session失效日期小于当前日期的数据删除
        request.session.clear_expired()
    
        # 检查 用户session的随机字符串 在数据库中是否
        request.session.exists("session_key")
    
        # 删除当前用户的所有Session数据
        request.session.delete("session_key")
    
        request.session.set_expiry(value)
            * 如果value是个整数,session会在些秒数后失效。
            * 如果value是个datatime或timedelta,session就会在这个时间后失效。
            * 如果value是0,用户关闭浏览器session就会失效。
            * 如果value是None,session会依赖全局session失效策略。
    

    八.Form组件

    Django的Form主要具有一下几大功能:

    生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容

    1.创建Form类 class UserInfo(models.Model): username = models.CharField() email = models.EmailField() user_type = models.ForeignKey() 2.参数

    Field
    required=True,               是否允许为空
    widget=None,                 HTML插件
    label=None,                  用于生成Label标签或显示内容
    initial=None,                初始值
    help_text='',                帮助信息(在标签旁边显示)
    error_messages=None,         错误信息 {'required': '不能为空', 'invalid': '格式错误'}
    show_hidden_initial=False,   是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)
    validators=[],               自定义验证规则
    localize=False,              是否支持本地化
    disabled=False,              是否可以编辑
    label_suffix=None            Label内容后缀
    

    3.字段

    CharField(Field)
        max_length=None,             最大长度
        min_length=None,             最小长度
        strip=True                   是否移除用户输入空白
    
    IntegerField(Field)
        max_value=None,              最大值
        min_value=None,              最小值
    
    FloatField(IntegerField)
        ...
    
    DecimalField(IntegerField)
        max_value=None,              最大值
        min_value=None,              最小值
        max_digits=None,             总长度
        decimal_places=None,         小数位长度
    
    BaseTemporalField(Field)
        input_formats=None          时间格式化   
    
    DateField(BaseTemporalField)    格式:2015-09-01
    TimeField(BaseTemporalField)    格式:11:12
    DateTimeField(BaseTemporalField)格式:2015-09-01 11:12
    
    DurationField(Field)            时间间隔:%d %H:%M:%S.%f
        ...
    
    RegexField(CharField)
        regex,                      自定制正则表达式
        max_length=None,            最大长度
        min_length=None,            最小长度
        error_message=None,         忽略,错误信息使用 error_messages={'invalid': '...'}
    
    EmailField(CharField)      
        ...
    
    FileField(Field)
        allow_empty_file=False     是否允许空文件
    
    ImageField(FileField)      
        ...
        注:需要PIL模块,pip3 install Pillow
        以上两个字典使用时,需要注意两点:
            - form表单中 enctype="multipart/form-data"
            - view函数中 obj = MyForm(request.POST, request.FILES)
    
    URLField(Field)
        ...
    
    
    BooleanField(Field)  
        ...
    
    NullBooleanField(BooleanField)
        ...
    
    ChoiceField(Field)
        ...
        choices=(),                选项,如:choices = ((0,'上海'),(1,'北京'),)
        required=True,             是否必填
        widget=None,               插件,默认select插件
        label=None,                Label内容
        initial=None,              初始值
        help_text='',              帮助提示
    
    
    ModelChoiceField(ChoiceField)
        ...                        django.forms.models.ModelChoiceField
        queryset,                  # 查询数据库中的数据
        empty_label="---------",   # 默认空显示内容
        to_field_name=None,        # HTML中value的值对应的字段
        limit_choices_to=None      # ModelForm中对queryset二次筛选
    
    ModelMultipleChoiceField(ModelChoiceField)
        ...                        django.forms.models.ModelMultipleChoiceField
    
    
    
    TypedChoiceField(ChoiceField)
        coerce = lambda val: val   对选中的值进行一次转换
        empty_value= ''            空值的默认值
    
    MultipleChoiceField(ChoiceField)
        ...
    
    TypedMultipleChoiceField(MultipleChoiceField)
        coerce = lambda val: val   对选中的每一个值进行一次转换
        empty_value= ''            空值的默认值
    
    ComboField(Field)
        fields=()                  使用多个验证,如下:即验证最大长度20,又验证邮箱格式
                                   fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
    
    MultiValueField(Field)
        PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用
    
    SplitDateTimeField(MultiValueField)
        input_date_formats=None,   格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y']
        input_time_formats=None    格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
    
    FilePathField(ChoiceField)     文件选项,目录下文件显示在页面中
        path,                      文件夹路径
        match=None,                正则匹配
        recursive=False,           递归下面的文件夹
        allow_files=True,          允许文件
        allow_folders=False,       允许文件夹
        required=True,
        widget=None,
        label=None,
        initial=None,
        help_text=''
    
    GenericIPAddressField
        protocol='both',           both,ipv4,ipv6支持的IP格式
        unpack_ipv4=False          解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用
    
    SlugField(CharField)           数字,字母,下划线,减号(连字符)
        ...
    
    UUIDField(CharField)           uuid类型
    

    4.常用选择插件 单radio,值为字符串 widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),)) 单select,值为字符串 widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)) 多选select,值为列表 widget=widgets.SelectMultiple 单checkbox widget=widgets.CheckboxInput() 多选checkbox,值为列表 widget=widgets.CheckboxSelectMultiple

    5.常用内置插件

    TextInput(Input)
    NumberInput(TextInput)
    EmailInput(TextInput)
    URLInput(TextInput)
    PasswordInput(TextInput)
    HiddenInput(TextInput)
    Textarea(Widget)
    DateInput(DateTimeBaseInput)
    DateTimeInput(DateTimeBaseInput)
    TimeInput(DateTimeBaseInput)
    CheckboxInput
    Select
    NullBooleanSelect
    SelectMultiple
    RadioSelect
    CheckboxSelectMultiple
    FileInput
    ClearableFileInput
    MultipleHiddenInput
    SplitDateTimeWidget
    SplitHiddenDateTimeWidget
    SelectDateWidget
    

    6.用于验证

    obj = XXOOModelForm()#创建验证对象
    obj.is_valid()                    #进行验证
    obj.errors                        #所有错误信息对象
    obj.clean()                      #用与用户自定义规则
    obj.cleaned_data            #获取的数据
    

    7.views处理

    def index(request):
    if request.method == "GET":
        obj = MyForm()
        return render(request, "index.html", {"obj": obj})
    elif request.method == "POST":
        obj = MyForm(request.POST, request.FILES)
        if obj.is_valid():
            v = obj.cleaned_data
            print("用户验证成功信息", v)
            return redirect("http://www.jd.com")
        else:
            v = obj.errors
            print("错误信息", v)
            return render(request, "index.html", {"obj": obj})  
    

    8.生成HTML标签

    <form action="/index/" method="post" enctype="multipart/form-data" novalidate>
        <p>{{ obj.user.label }}{{ obj.user }}{{ obj.user.errors.0 }}</p>
        <p>{{ obj.gender.label }}{{ obj.gender }}{{ obj.gender.errors.0 }}</p>
        <p>{{ obj.pwd.label }}{{ obj.pwd }}{{ obj.pwd.errors.0 }}</p>
        <p>{{ obj.city.label }}{{ obj.city }}{{ obj.city.errors.0 }}</p>
    
        <input type="submit" value="提交">
    </form>
    
  • 相关阅读:
    MVC5+EF6 入门完整教程七
    MVC5+EF6 入门完整教程六
    MVC5+EF6 入门完整教程五
    MVC5+EF6 入门完整教程四
    MVC5 + EF6 完整入门教程三
    MVC5 + EF6 入门完整教程二
    MVC5 + EF6 入门完整教程
    最短路径简析
    PAT 1147 Heaps
    PAT 1146 Topological Order
  • 原文地址:https://www.cnblogs.com/kimyeee/p/7145202.html
Copyright © 2020-2023  润新知