django

django:
    django-admin startproject myweb
    目录结构
        myweb
        - myweb
            - init      //python2必须要有,没有别人没法导入
            - settings  //配置文件
            - url       //url对应关系
            - wsgi      //遵循wsgi规范,wsgi是规则是接口,创建socket用的
        - manage.py     //管理django程序:
            python3 manage.py runserver 127.0.0.01:8001
            python3 manage.py startapp xx
            python3 manage.py makemigrattions
            python3 manage.py migrate

        app:
            共同使用一个配置文件
            python3 manage.py startapp app_name

            app目录都有什么
                - apps          //对当前app最配置管理
                - admin         //django默认管理程序
                - migrations    //数据库修改表结构
                - models        //创建数据库表
                - tests         //单元测试
                - views         //业务逻辑

        settings:
            //配置模板路径
                TEMPLATES = [
                    {
                        'BACKEND': 'django.template.backends.django.DjangoTemplates',
                        'DIRS': [os.path.join(BASE_DIR, 'templates')]       ,    //模板路径
                        'APP_DIRS': True,
                        'OPTIONS': {
                            'context_processors': [
                                'django.template.context_processors.debug',
                                'django.template.context_processors.request',
                                'django.contrib.auth.context_processors.auth',
                                'django.contrib.messages.context_processors.messages',
                            ],
                        },
                    },
                ]

    STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
    '/var/www/static/',
]



            //CSRF报警
                django.middleware.csrf.CsrfViewMiddleware'

            //获取用户提交方法
                request.method

            //获取自定义的name,没有name是none
                request.body                                    //POST,GET都是利用这个http的body
                    user = request.POST.get('user', None)       //操作文件的话默认只能拿到文件名
                    user = request.GET.get('user', None)
                    user = request.FILES.get('user', None)
                    user = request.POST.getList('user', None)   //获取checkbox等多选
                request.Meta                                    //获取http请求头的
                    request.method(POST,GET,PUT)
                    request.path_info
                    request.COOKIES

                <form enctype="multipart/form-data">
                file = request.FILES.get('file_name')
                print(file_name, type(file_name), file_name.name)
                file_path = os.path.join('upload', file_name.name)
                for i in obj.chunks():
                    f.write(i)
                f.close()

    基础用法
        //前端接收后端的值
            前端
                <span style="color:red">{{ error_msg }}</span>
            后端
                return render(request, 'login.html', {'error_msg': error_msg})
        //跳转超链接
            from django.shortcuts import redirect
            return redirect('http://www.baidu.com')     //只能填url
        //返回字符串:
            return HttpResponse("dasdsadsad")           //接收字符串,字节
        //模板语言的for循环
            list action:
                list_1 = [
                    {'username': '123'}
                    {'gender': 1}
                    {'email': "dwa@qwe.com"}
                ]
                {% for item in list_1 %}
                    <tr>
                        <td>{{ row.username }}</td>
                        <td>{{ row.gender.key1s  }}</td>
                        <td>{{ row.email }}</td>
                        <td>{{ forloop.counter }}</td>       //计数器, 从1开始
                        <td>{{ forloop.counter0 }}</td>      //计数器, 从0开始
                        <td>{{ forloop.revcounter }}</td>    //计数器, 倒序
                        <td>{{ forloop.last }}</td>          //是否是最后一个
                        <td>{{ forloop.first }}</td>         //是否是第一个
                    </tr>
                {% endfor %}
            dict action:
                dict_1 = {
                    'k1': 'v1',
                    'k2': 'v2',
                    'k3': 'v3',
                    'k4': 'v4'
                }
                {% for k in dict_1.keys %}          //print keys
                {% for v in dict_1.values %}        //print values
                {% for k, v in dict_1.items %}      //print keys, values
                    <tr>
                        <td>{{ k }}</td>
                        <td>{{ v }}</td>
                        <td>{{ k }} ---> {{ v }}</td>
                    </tr>
                {% endfor %}

            {% if condition%}
                segment
            {% else %}
                segment
            {% endif %}

    路由系统:
        FBV:
            function base view
            url里对应的是一个函数
        CBV
            class base view
            也可以对应一个class
                path(r'haha/', login_views.Home.as_view()),     //as_view()固定用法

            函数能根据方法类型响应方法,如get,post,head,put,patch,delete,options.trace
            from django.views import View                       //必须继承自view类
            class Home(View):
                def get(self, request):
                    print(request.method)
                    return render(request, 'home.html')

                def post(self, request):
                    print(request.method)
                    return render(request, 'home.html')

        正则匹配:
            直接在url里传值了, 不是get和post, 这样SEO优化看来是静态页面
            http://0.0.0.0:22222/detail-3.html
            urls:
                from django.urls import re_path
                re_path(r'^detail-(d+).html', login_views.detail),
                re_path(r'^detail-(?P<username>d+)-(?P<password>d+).html', login_views.detail),
            app.views:
                def detail(request, nid):
                def detail(request, *args, **kwargs):
                    return HttpResponse(nid)

        name:
            对URL路有关系命名, 更简便的生成一个URL
            urls
                path(r'haha/', login_views.Home.as_view(), name='home11')
            模板语言
                {% url "home11" 1 2 3 %}            //参数以空格隔开

            reverse:
                //根据name生成一个url
                from django.urls import reverse
                v = reverse('home11', args=(33,22,))
                v = reverse('home11', kwargs=('username': 33,'password': 22,))

        URL分类 :
            from django.conf.urls import url.include

            urlpatterns = [
                path(r'cmdb', include('cmdb.urls')),
            ]

            //在名字为cmdb的app里创建一个py文件叫做urls,然后正常写入规则


        默认值
        命名空间


    ORM:
        Object relation Map
        DB first: 先创建表,再生成类
            pass
        Code first: 先创建类,再生成表
            1.根据类自动创建数据库表
            2.根据类对数据库表中的数据进行各种操作

        注册app:
            INSTALLED_APPS = [
                'django.contrib.admin',
                'django.contrib.auth',
                'django.contrib.contenttypes',
                'django.contrib.sessions',
                'django.contrib.messages',
                'django.contrib.staticfiles',
                'login',                        //在settings里添加上这个app, 不然无法使用 makemigrations
            ]

        from django.db import models

        // Create your models here.

        model文件中的表(类)定义
            class UserInfo(models.Model):
                // auto create id column auto increment
                // create user column & figer length
                username = models.CharField(max_length=32)      // 字符长度
                // create passwd column & figer length
                password = models.CharField(max_length=64)
                // value can be true
                gender = models.CharField(max_length=10, null=True)

        python3 manage.py makemigrations    //生成数据库临时文件
        python3 manage.py migrate           //生成数据库内容, 默认情况下是SQLite, 表名是AppName_TableName

        django默认使用mysqldb
        mysqldb解决办法
        MySQL:
            配置
                DATABASES = {
                    'default': {
                        'ENGINE': 'django.db.backends.mysql',       // 驱动(ENGINE)
                        'HOST': '192.168.20.61',                    // 主机地址(HOST)
                        'PORT': '3306',                             // 端口号(PORT)
                        'NAME': 'hinimix',                          // 数据库(NAME)
                        'USER': 'hinimix',                          // 用户名(NAME)
                        'PASSWORD': 'hinimix',                      // 登录密码(PASSWORD)

                    }
                }
            执行
                sudo apt install python-dev
                sudo apt-get install libmysqlclient-dev
                sudo pip3 install mysqlclient

                python3 manage.py makemigrations

                python3 manage.py migrate


        pymysql解决办法
            在app目录里
                import pymysql
                pymysql.install_as_MySQLdb()

        CRUD操作:
            Create:
                from login import models
                1
                    models.UserInfo.objects.create(
                        username='root',
                        password='123'
                    )
                2
                    obj = models.UserInfo(username='sb', password='234')
                    obj.save()
                3
                    dict = {'username': 'hnm', 'password': '21'}
                    obj = models.UserInfo(**dict)
                    obj.save()
            Retrieve
                result = models.UserInfo.objects.all()      // QuerySet,内部元素是对象, result QuerySet类型 ==>LIST
                result = models.UserInfo.objects.all().values('comuln1', 'column2') // QuerySet,内部元素是字典, result QuerySet类型 ==>LIST
                result = models.UserInfo.objects.all().values_list('id', 'caption') // QuerySet,内部元素是元组,
                 // result QuerySet类型 ==>LIST
                result2 = models.UserInfo.objects.filter(username='hnm', password='21')     //组合城and条件
                result2 = models.UserInfo.objects.filter(username='hnm', age__gt='21')     //组合城and条件,age大于21
                dic = {'username': 'hnm', 'password':'21'}
                result2 = models.UserInfo.objects.filter(**dic)     //组合城and条件,可以用字典
                result2 = models.UserInfo.objects.filter(username='hnm', password='21').first()     //直接是一个对象
                result2 = models.UserInfo.objects.filter(username='hnm', password='21').count()     //个数
            Update
                result = models.UserInfo.objects.all().update(password='666)
                result2 = models.UserInfo.objects.filter(username='hnm', password='21').update(password='666')     //值为1或0
            Delete
                result = models.UserInfo.objects.all().delete()      // result QuerySet类型 ==>LIST
                result2 = models.UserInfo.objects.filter(username='hnm', password='21').delete()

            print(result.query)             // 查看执行过程



        Django admin
            Django ORM字段类型
                test0 = models.CharField(max_length=64)
                test1 = models.EmailField(max_length=30, null=True)
                test2 = models.URLField(max_length=100)
                test3 = models.GenericIPAddressField(max_length=20)     // IPv4 | IPv6
                test4 = models.AutoField(primary_key=True)              // auto increment

            把表注册到admin
                // 在admin文件里添加以下内容, 能通过django admin来管理login的数据库
                from login import models
                // Register your models here.
                admin.site.register(models.UserInfo)

            python3 manage.py createsuperuser
            Django会自动检查test字段里的字符串是否符合Email格式

            参数:
                null                //允许为空
                default             //默认值
                primary_key         //主键
                db_column           //列名
                db_index            //索引
                unique              //唯一索引
                unique_for_date     //对日唯一索引
                unique_for_month    //对月唯一索引
                unique_for_year     //对年唯一索引
                auto_now            //创建时自动生成
                auto_now_add        //更新时自动更新
                    test5 = models.DateField(auto_now_add=True, null=True)
                    test6 = models.DateField(auto_now=True, null=True)

                    result = models.TestInfo.objects.create(test7='aa')
                    result.save()
                choices             //在django admin里提示选项
                    user_type_choice = (
                        (1, 'super user'),
                        (2, 'midle user'),
                        (3, 'lower user')
                    )
                    user_type_id = models.IntegerField(choices=user_type_choice, default=1)
                blank = True:       //在django admin中可以为空
                verbose_name:       //在django admin中显示的中文字符
                editable:           //在django admin中是否能被编辑
                error_message       //在django admin中错误信息
                help_text           //在django admin中提示
                validators          //在django admin中自定义验证机制

            外键:
                class UserType(model.Model):
                    caption = models.CharField(max_length=32)

                class User(models.Model):
                    age = models.IntergerField()
                    name = models.CharField(max_length=10)
                    user_type = models.ForeignKey("UserType", to_field='id')    // 约束

            跨表:
                写在objects后面, 都是用__跨表
                其他时候,用.跨表


    AJAX
        不用像form一样提交之后刷新页面
        依赖JQuery
        最简单的固定格式
            $.ajax({
                url: '/host',                   //目标地址
                type: "POST",                   //提交方法
                data: {'k1':123, 'k2':456},     //提交的值
                data: $(//form_name)/serialize(),     //获取form的值一起获取,发给后台
                success: function(data){        //匿名回调函数

                }
            })

            $.get
            $.post
            $.getJson


            建议,永远让服务器端返回一个字典, ajax通过status判断取error还是data
                dict = {'status': True, 'error': None, 'data':None}
                return HttpResponse(json.dumps(dict))

            前端获取字符串转化为对象
                JSON.stringify(obj)      //对象转换为字符串
                JSON.parse(str)         //字符串转化为对象

                var obj = JSON.parse(data)  //将后端来的值变成了
                $('//error_box').text(obj.error())

            后端代码
                def test_ajax(request):
                    a = request.GET.get('user')
                    b = request.GET.get('password')
                    print(a, b)
                    return HttpResponse(a, b)

        多对多:
            自定义关系:
                class Host(models.Model):
                    nid = models.AutoField(primary_key=True)
                    hostname = models.CharField(max_length=32, db_index=True)
                class Application(models.Model):
                    name = model.CharField(max_length=10)
                class HostToApp(models.Model):
                    hobj = models.ForeignKey(to='Host', to_field='nid')
                    aobj = models.ForeignKey(to='Application', to_field='id')
            自动创建关系表:
                class xxx(models.Model):
                    r = models.ManyToManyField("Other_table_name")

                obj = xxx.objects.get(id=1)
                obj.r.add(1)
                obj.r.add(2, 3, 4)
                obj.r.add(*[1,2,3,4])       //增加多个关系
                obj.r.remove(1)
                obj.r.remove(2, 3, 4)
                obj.r.remove(*[1,2,3])      //删除多个关系

                obj.r.clear()               //清除xxx id=1的
                obj.r.set([3, 5, 7])


    模板:
        继承:
            {% extends 'muban.html' %}      //继承muban.html
            {% block css %}{% endblock %}   //方便写自己的css

            {% block muban_name %}          //定义模板中的block
            <a> aaaaa aa  </a>
            {% endblock %}                  //在html中补足内容

            {% block js %}{% endblock %}    //方便写自己的js

        导入:
            {% include "tag.html" %}        //在当前位置导入tag.html

        simple tag帮助方法:
            {{ item.event_start|date:"Y-m-d H:i:s" }}       //item接收后台的字符串,按指定类型输出
            {{ bio|truncatewords: "30" }}       //bio:后台传过来的字符串, 只保留前30
            {{ my_list|first|upper }}           //my_list首字母大写
            {{ name|lower }}                    //name全小写

        自定义simple tag(前端使用后端的函数):
            1.在app下创建templatetags文件夹
            2.创建任意py文件
            3.引入django.utils.safestring中的mark_safe
            4.创建一个template对象register,不能改名
            5.定义函数加上装饰器
            6.settings文件中注册app
            7.在静态顶部{% load 文件名 %}
            8.在静态下面引用函数名 {% function_name %}

            settings:
                INSTALLED_APPS= {
                    app_name,
                }
            后端:
                app下templatetags
                写入xxoo.py
                from django import template
                from django.utils.safestring import mark_safe

                register = template.Library()

                @register.simple_tag
                def hinimix(argv1, argv2):
                    return 123

            前端:
                {% load xxoo.py %}
                {% hinimix argv1   argv2 %}     //有空格没关系
            缺点:
                不能作为if条件
            优点:
                参数任意
        filter:
            register = template.Library()
            @register.filter
            {{ "aaa"|hinimix:"argv1,argv2" }}
            缺点:
                参数最多2个,不能加空格
                {{ "参数1"|函数名:"参数2,参数3" }}
            优点:
                能作为if条件

        自定义分页:
            xss:
                前端:
                    {{ page_str|safe }}
                后端:
                    mark_safe(page_str)

    装饰器认证登录:
        FBV:
            def auth(func):
                def inner(request, *args, **kwargs):
                    v = request.COOKIES.get('username')
                    if not v:
                        return redirect('/login/')
                    return func(request, *args, **kwargs)
        CBV:
            from django.utils.decorators import method_decorator
            在class里添加
            @method_decorator(auth)
            def dispatch(self, request, *args, **kwargs)
                return super(Order, self).dispatch(request, (args, **kwargs)
            或

            @method_decorator(auth, name='dispatch')
            class Order(views.View):
                pass
cookie:
    存放在浏览器上的一个文件, 关闭浏览器失效
    result = redirect('/index/')
    res.set_cookie('username', u, max_age=100)      //max_age cookie过期时间,单位s
    current_date = datetime.datetime.utcnow() + datetime.timedelta(seconds=5)
    res.set_cookie('username', u, expires=currend_date)      //expires cookie过期时间 datetime类型
    return res

    response=HttpResponse(a)
    response.set_cookie('key', "value", expires[current_date)
    response['name'] = 'hinimix'                //自定义响应头
    return response

    obj = HttpResponse('s')
    obj.set_signed_cooke("key_name", "value_name", salt="asdsad")             //加密cookie
    request.get_signed_cooke("key_name", salt="asdsad")                         //解密cookie
    其他参数:
        path= "/"       //生效路径, /表示默认所有url里都生效
        domain=None     //生效域名,当前域名或子域名
        secure=false    //true:支持https
        httponly=True   //只支持http传输, 不会通过js获取到

    v = request.COOKIES.get('username')


session:
        敏感信息不适合放在cookie中,适合放在session中
        是保存在服务器端的键值对, 依赖于cookie

        // 所有键, 值, 键值对
        request.session.keys()
        request.session.iterkeys()
        request.session.values()
        request.session.itervalues()
        request.session.items()
        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['k1'] = 123
            request.session.setdefault('k1', 123)   #存在则不设置

            del request.session['k1']

            request.session.set_expiry(value)
                //如果value是证书,session会在这些秒之后失效
                //如果value是datetime或者timedelta, session就会在这个时间后失效
                //如果value是0, 用户关闭浏览器session就会失效
                //如果value是None, session会依赖全局session失效策略.
                //默认是2周

        Django Session通用配置
            SESSION_COOKIE_NAME = "sessionid"       //sessin的cookie保存在浏览器上时候key的名字
            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


        //用缓存存储session,引擎配置
            #SESSION_ENGINE = 'django.contrib.sessions.backends.cache'    //引擎
            SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
            SESSION_CACHE_ALIAS = 'default'
            SESSION_SAVE_EVERY_REQUEST = True

原文地址:https://www.cnblogs.com/hinimix/p/9318966.html