django 武沛齐老师-最后一篇随笔

基础
https://www.cnblogs.com/wupeiqi/articles/5237704.html

进阶
https://www.cnblogs.com/wupeiqi/articles/5246483.html

安装
    pip install django==1.11.14 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

卸载
    pip uninstall django

创建 django 项目
    django-admin startproject 项目名
    django-admin startproject victory

运行 django 项目
    cd victory
    python manage.py runserver

创建 app
    python manage.py startapp app名称
    python manage.py startapp app01

urls 文件
    urlpatterns = [ ]  对应 url 映射的列表
    urlpatterns = [
        url(r'^网址名称/', 包模块.函数名),
        url(r'^网址名称/', 函数名),
    ]

wsgi 一套规则,接口,创建 socket
    产品上线不使用默认的 wsgi , 使用 uwsgi + nginx

manage.py 管理 django 程序

settings 配置文件
    app 注册
        app 名称.apps.app 名称Config 或 app 名称
        app01.apps.App01Config 或 app01

    templates 模板注册
        'DIRS': [os.path.join(BASE_DIR, 'templates')],

    配置静态文件夹 static
        创建 static 静态文件夹
            STATICFILES_DIRS = (
                os.path.join(BASE_DIR,'static'),
            )

    设置中文
        LANGUAGE_CODE = 'zh-hans'

    设置时区
        TIME_ZONE = 'Asia/Shanghai'

    设置数据库为 mysql (注:先安装 mysqlclient, pip install mysqlclient)
        DATABASES = {
            'default': {
                'ENGINE': 'django.db.backends.mysql',
                'NAME': '数据库名称',
                'USER':'用户名',
                'PASSWORD':'密码',
                'HOST':'127.0.0.1',
                'PORT':'3306'
            }
        }

        DATABASES = {
            'default': {
                'ENGINE': 'django.db.backends.mysql',
                'NAME': 'app02',
                'USER':'root',
                'PASSWORD':'root',
                'HOST':'127.0.0.1',
                'PORT':'3306'
            }
        }

ORM 对象关系映射,创建数据库表不需要使用select , insert 语句了
    数据库迁移
        python manage.py makemigrations
        python manage.py migrate

app 目录
    migrations 记录做过哪些修改数据表结构的操作
    __init__ 文件,python3 可以删除,python2 不可以删除
        python2 默认 不带 __init__ 文件为普通文件夹,导入会报错
    admin 后台管理
        在 admin 中,导入 app 的 models 文件
            from app01 import models
        将 models 里面的数据表进行注册
            admin.site.register(models.UserInfo)
            admin.site.register(models.UserType)
        两张表内容如下
            class UserType(models.Model):
                name = models.CharField(max_length=32)

            class UserInfo(models.Model):
                username = models.CharField(max_length=32)
                pwd = models.CharField(max_length=32)
                email = models.CharField(max_length=32)
                user_type = models.ForeignKey('UserType')
                # 使用 '' 将类名包裹,进行创建外键


        创建超级用户
            python manage.py createsuperuser
            示例:
                用户名 hany
                密码 hany12345.
        超级用户登录后,可以对数据表增加数据等操作

    apps 配置当前 app
    models ORM 操作,通过命令创建数据库表结构
    tests 单元测试
    views 业务逻辑文件,写函数



伪装数据库
    项目的 __init__ 文件下
        import pymysql
        pymysql.install_as_MySQLdb()

生命周期
    用户发送请求到路由系统,如果匹配成功,执行相对应的 views 中的函数
        到数据库中取出数据,在模板 html 上进行页面渲染数据 返回到用户的浏览器上

urls 操作
    url(r'^路由映射/', views.函数名),
    url(r'^register/', views.register),

    url(r'^路由映射-(?P<形参名>d+).html', views.函数名),
    url(r'^detail-(?P<cid>d+).html', views.detail),

    url(r'路由映射',include("app名称.urls"))
    url(r'app02',include("app02.urls"))
        注:include 内参数加引号,urls 需要自己创建
           在用户创建的 urls 中,继续进行地址映射,写在 urlpatterns = [ ]中
           app 不要忘记在 settings 中进行注册


models 操作
    创建数据表时,继承 models.Model
        示例
            class UserInfo(models.Model)

    创建字符串类型数据 models.CharField
        示例
            username = models.CharField(max_length=32)

    id 主键会自动创建,并递增
        使用 AutoField,并且声明主键 primary_key=True 可以不让系统创建 id 列
        示例
            uid = models.AutoField(primary_key=True)
    字段参数
        null 字段是否为空
        default 默认值
            示例
                code = models.CharField(max_length=32,null=True,default="SA")
        primary_key 主键
        db_column 列名
        db_index 索引 , unique 唯一索引
        unique_for_date 对日期做索引,unique_for_month 对月做索引, unique_for_year 对年做索引
        auto_now=True 创建时生成时间
            示例
                ctime = models.DateField(auto_now=True,null=True)
        auto_now_add=True 修改时自动更新时间
        choice 选项
        示例 , choices 为 一个嵌套的元组对象
            user_type_choices = (
                (1,'super man'),
                (2,'common man'),
                (3,'man'),
            )
            user_type_id = models.IntegerField(choices=user_type_choices,default=2)
        verbose_name 备注字段
        editable 字段是否可以被编辑
        help_text 字段输入提示
        validators 自定义错误信息
        to_field 与哪一列进行关联

    创建整数类型数据 models.IntegerField
        示例
            user_type_id = models.IntegerField(choices=user_type_choices,default=2)
    外键关联 models.ForeignKey
        示例 第一个参数为类名,uid 为关联的字段
            usergroup = models.ForeignKey('UserGroup',to_field='uid')
        会自动生成 usergroup_id 列,usergroup 为对象,可以使用 usergroup.uid 进行获取外联表的数据
    创建 ip 
        示例 , protocol默认为 'both'
            ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
       多对多 , 不能加额外字段列
           models.ManyToManyField('类名')

       一对多,多对多示例
        class Business(models.Model):
            caption = models.CharField(max_length=32)
            code = models.CharField(max_length=32,null=True,default="SA")


        class Host(models.Model):
            nid = models.AutoField(primary_key=True)
            hostname = models.CharField(max_length=32,db_index=True)
            ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
            port = models.IntegerField()
            b = models.ForeignKey(to="Business", to_field='id')

        class Application(models.Model):
            name = models.CharField(max_length=32)
            r = models.ManyToManyField("Host")
                注:会自动创建一个新的表,内部为其他表的 id 主键

        obj = Application.objects.get(id=1)
        增加数据
            obj.r.add(1)
            obj.r.add(1,2,3)
            obj.r.add(*[1,2,3])
        删除数据
            obj.r.remove(2,4,5)
            obj.r.clear()
        更新数据
            obj.r.set([3,5,7])

    多对多 , 自定义创建第三张表 , 可以自己定义第三张表的字段
        示例
            class HostApp(models.Model):
                hobj = models.ForeignKey(to='Host',to_field='nid')
                aobj = models.ForeignKey(to='Application',to_field='id')
                status = models.CharField(max_length=32)
        增加数据
            HostApp.objects.create(hobj_id='xxx',aobj='xxx',status='xxx')

html 操作
    
    导入 jquery
        <script src="/static/jquery.min.js"></script>
    导入静态文件
        <link rel="stylesheet" href="/static/commons.css">

    使用 {{ 变量名 }} 进行显示变量
        <span style="color: red;">{{ error_msg }}</span>

    for 循环
        {% for 对象 in 传递过来字典的键 %}
            <ul>
                <li> {{ 对象 }} </li>
            </ul>
        {% endfor %}

        遍历字典中的键
            {% for num in user_num.keys %}
                <ul>
                    <li> {{ num }} </li>
                </ul>
            {% endfor %}

        遍历字典中的值
            {% for num in user_num.values %}
                <ul>
                    <li> {{ num }} </li>
                </ul>
            {% endfor %}

         遍历字典的所有元素
            {% for key,value in user_num.items %}
                <ul>
                    <li> {{ key }} - {{ value }}</li>
                </ul>
            {% endfor %}

        遍历列表
            {% for name in user_list %}
                <ul>
                    <li> {{ name }} </li>
                </ul>
            {% endfor %}

    取索引对象
        第一个元素
            对象.0   {{ user_list.0 }}
        对应索引元素名
            对象.元素名  {{ user_num.zero }}

    if 语句
        {% if 条件%}
            语句
        {% else %}
            语句
        {% endif %}

        {% if 条件 %}
            语句
        {% elif 条件 %}
            语句
        {% else %}
            语句
        {% endif %}

    跳转链接 href
        <a href="app名称/路由">内容</a>
        示例 , 跳转到 app02 下的 student 中
            <a class="menu" href="/app02/student">学生管理</a>

    循环计数 forloop
        从 1 开始
            {{ forloop.counter }}
        从 0 开始
            {{ forloop.counter0 }}
        是否是第一个 , 返回 True 或 False
            {{ forloop.first }}
        是否是最后一个 , 返回 True 或 False
            {{ forloop.last }}
        倒序到 1 为止
            {{ forloop.revcounter }}
        倒序到 0 为止
            {{ forloop.revcounter0 }}
        上一层循环
            {{ forloop.parentloop }}

    ajax
        $.ajax({
            url:"路由地址",
            type:"GET 或 POST 请求方式",
            data:数据,  data: $('#select 标签的 id 值').serialize(), 获取序列化数据
            dataType:'数据类型'
            success: function(data){
                对获取到的数据 data 要进行的操作
                JSON.parse(data) 对返回的字符串转换为对象
                location.reload(), 刷新
                location.href = '某个地址' ,  跳转

            }
        }

views 操作
    形参可以使用 request , *args , **kwargs

    request.method 提交方式
        GET , POST 以及其他方式

    request.environ 获取所有的请求信息

    获取 cookies
        request.COOKIES
    获取用户输入的值
        request.POST['html 中的name 属性的值']
        request.POST.get('html 中的name 属性的值',None)
        password = request.POST.get('password',None)

        request.POST.getlist('html 中的name 属性的值')
        request.POST.getlist('favor')

    返回页面上显示的字符串
        return HttpResponse('<标签名>字符串</标签名>')
        return HttpResponse('<h2>Hello</h2>')

    页面跳转
        return redirect('网址')
        return redirect('/home/')
           注: home 前面的 / 为 ip : 端口号/

    页面渲染
        return render(request,'html文件名.html'[,变量])
        return render(request,'login.html')
        return render(request,'login.html',{'error_msg':error_msg})
            注: 字典的键为在 html 中使用的变量名称

    数据库增删改查
        字段值大于 1 的
            models.类名.objects.filter(字段__gt=1)
        字段值大于等于 1 的
            models.类名.objects.filter(字段__gte=1)
        字段值等于 1 的
            models.类名.objects.filter(字段=1)
        字段值小于 1 的
            models.类名.objects.filter(字段__lt=1)
        字段值小于等于 1 的
            models.类名.objects.filter(字段__lte=1)
        获取指定字段的值
            models.类名.objects.all().values('字段1','字段2')
                注:返回的是 QuerySet 类型,内部为字典对象
            models.类名.objects.all().values_list('字段1','字段2')
                注:返回的是 QuerySet 类型,内部为元组对象
            示例
               models.UserInfo.objects.all().values('username', 'password')

    获取文件
        注: 在文件上传时,在 form 表单中加入 enctype="multipart/form-data" 表示上传的是文件
        上传的文件到 request.FILES 中进行查找
            file = request.FILES.get('html 中的name 属性的值')
            file.chunks()  一个可迭代对象,包含有上传的文件
            file.name 文件名
            file.size 文件大小

        获取上传文件示例(fff 为 name 的值,upload为在项目根路径下创建的文件夹):
            file = request.FILES.get('fff')
            import os
            file_location = os.path.join('upload',file.name)
            f = open(file_location,mode = 'wb')
            for i in file.chunks():
                f.write(i)
            f.close()

    根据用户点击的不同,生成不同的详细信息
        示例:
            views 中:
                user_info = {
                    '1':['xiaoming','nv','21'],
                    '2':['xiaolang','nan','22'],
                    '3':['xiaomi','nv','23'],
                    '4':['xiaole','nan','24'],
                }

                def index(request):
                    return render(request,'index.html',{'user_info':user_info})

                def detail(request,cid):
                    detail_info = user_info[cid]
                    return render(request,'detail.html',{'detail_info':detail_info})

            urls 中
                url(r'^detail-(?P<cid>d+).html',views.detail),
                    在括号中写入 ?P<cid> 表示传递给形参 cid

            html
                index 中
                    {% for user_key in user_info.keys %}
                        <a href="/detail-{{ user_key }}.html">{{ user_key }}</a><br/>
                    {% endfor %}

                detail 中
                    <h2>详细信息</h2>
                    <div style="margin: auto;color: burlywood">
                        用户名:{{ detail_info.0 }}<br/>
                        性别:{{ detail_info.1 }}<br/>
                        年龄:{{ detail_info.2 }}<br/>
                    </div>
    获取当前 url
        request.path_info

    增加数据
        第一种
            models.类名.objects.create(
                字段1=值1,
                字段2=值2,
                  ...
            )
        示例
            models.UserInfo.objects.create(
                username='www',
                password='111'
            )
        第二种
            obj = models.类名(字段1=值1,字段2=值2)
            obj.save()
        示例
            obj = models.UserInfo(username='two',password='...')
            obj.save()

    查询数据
        查询全部数据
            models.类名.objects.all()
            示例 username 为字段名
                all = models.UserInfo.objects.all()
                for user in all:
                    print(user.username,user.password)
        查询指定某一行数据
            models.类名.objects.filter(字段1=值1[,字段2=值2])
            示例,对查询到数据可以进行循环输出数据
                result = models.UserInfo.objects.filter(username='hany')
                for user in result:
                    print(user.username,user.password)
        示例 , 获取外键所在表的数据 , 外键名为 b 通过.进行获取数据,b_id 为在表中的字段
            v1 = models.Host.objects.filter(nid=1).first()
            print(v1.nid,v1.hostname,v1.ip,v1.port,v1.b_id)
            print(v1.b.id,v1.b.caption)
            注:如果报错,可以考虑使用 __ 进行查询 b__caption
                v2 = models.Host.objects.filter(nid=1)
                print(v2.values('b__caption'))

    删除数据
        删除全部数据
            models.类名.objects.all().delete()
            示例
                models.UserInfo.objects.all().delete()
        删除一条数据
            models.类名.objects.filter(条件).delete()
            示例
                models.UserInfo.objects.filter(username='www').delete()
    更新数据
        更新全部数据
            models.类名.objects.all().update(字段=值)
            示例
                models.UserInfo.objects.all().update(password='666')
        更新一条数据
            models.类名.objects.filter(条件).update(字段=值)
            示例
                models.UserInfo.objects.filter(id=1).update(password='111')

    filter 后可以跟
        count() 获取数据个数
        示例 , 当不存在对应数据时,obj_count 为 0
            obj_count = models.UserInfo.objects.filter(username=username,password=password).count()
            print(obj_count)
        first() 获取第一条数据
        示例 , 使用了 first 之后,可以使用对象直接输出字段值
            obj = models.UserInfo.objects.filter(username=username,password=password).first()
            print(obj.username)
        登录示例 , 没有获取到数据为 None
            if not obj:
                error_msg = 'name or password is error '
                return render(request,'登录.html',{'error_msg':error_msg})
            else:
                return render(request, '主页.html')

问题
    SyntaxError: Generator expression must be parenthesized (widgets.py, line 152) 问题
        去掉最后面的 , 号
    跨站请求伪造 Forbidden (403) CSRF verification failed. Request aborted.
        找到 settings 中的 MIDDLEWARE 将 csrf 注释掉
    You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set.
        模板中提交的 action 数据要和 urls 的 urlpatterns 的 网址名称一样,要么都带 / , 要么都不带 /

2020-08-17

原文地址:https://www.cnblogs.com/hany-postq473111315/p/13515923.html