zoukankan      html  css  js  c++  java
  • Django个人工作总结

    Django个人工作总结

     

     

    API:https://docs.djangoproject.com/zh-hans/2.1/

    DCIM:https://www.dicomstandard.org/current/

    ADMIN:https://www.cnblogs.com/caseast/p/5909987.html

     

    POST请求要加csrf

    页面竖直滚动

    form表单提交遇到的问题

    django模板for循环和表单提交

    django传输数据限制

    django上传文件

    django返回ajax数据

    django返回页面并渲染模板

    django模板中使用富文本标签

    django的HttpRequest

    Django内置模板标签和过滤器

    Django自定义模板【过滤器】

    Django中混合使用artTemplate

    Django--render()

    Django--local()

    日期格式处理

    django order_by

    django filter

    shutil模块递归删除文件目录

    Django 只查询单个字段

    Django 查询结果返回前台出现' 或者 "

    Django 批量插入

    Django 原生SQL

    Django 事务回滚

    Django url传递参数

    Django 生成和执行requirements.txt

    Django 配置打印sql日志

    Django 使用Oracle11g遇到的坑

    Django 启动时执行任务

    Django 如何优雅的停止

    关于跨域请求session的问题

    关于拦截器中修改response问题

     

     

     

     

    POST请求要加csrf

    最重要的:大脑不清晰,想用ajax请求将数据传递后台,但是还想跳转页面,这目前以我的技术还达不到。后台是没办法改变浏览器地址的,后台只能将数据渲染到页面上,而只有你浏览器访问页面了才看得到,不访问,后台怎么渲染你还是看不到,这就是后台不能帮你在浏览器跳转所导致的问题。所以只有修改浏览器地址了。

    毛毛给的建议是使用window.location.href修改浏览器地址,细细想,如果我用ajax请求后台,将数据提交到后台后,然后将后台处理的数据渲染到另一个页面上,然后在ajax的success里使用window.location.href去修改浏览器地址,按理说应该也是行得通的,没试过。

    最后我还是使用了form表单,将数据提交到后台的。

     

    后台获取post请求要在方法上加注解。

    from django.views.decorators.csrf import csrf_exempt
    
    @csrf_exempt

    页面:

     <!--病例表单-->
    <form id="case_form">
       {% csrf_token %}
    </form>

    获取前台提交的数据:

    request.POST

    由于前台到后台django是使用QueryDict封装的,request.POST的结果是一个QueryDict,这是一个特殊的字典,有关该字典,可以看下面的链接了解。

    https://www.cnblogs.com/scolia/p/5634591.html

     

    还有就是后台提交的数据在前台变成乱码的问题,只需要在重定向后添加:

    return render(request, 'survey/hys_result.html', context,content_type="application/json,charset=utf-8")

    content_type="application/json,charset=utf-8" 即可,这是用于返回json格式的,如果不是用于ajax规定的json把application/json去掉即可。

     

    ajax的post请求后台:

    from django.shortcuts import render
    from django.http import HttpResponse
    from django.views.decorators.csrf import csrf_exempt
    import json
    
    
    def index(request):
        return render(request, 'index.html')
    
    @csrf_exempt
    def from_case(request):
        if request.method == 'POST':
            sex = request.POST['sex']
            print(sex)
            return HttpResponse(json.dumps({'sex': 123}), content_type='application/json')

    ajax js:

    /*表单提交事件*/
    $('#send').click(function () {
        var data = $('#from_case').serialize();
        $.ajax({
            type: 'POST',
            url: '/sdd/from_case/', // 链接地址以/开头以/结尾
            async:false,
            data: data,
            dataType: 'json',
            success: function (result) {
                console.log(result);
            },
            error:function (error) {
                console.log(error)
            }
        })
        return false; // 阻止button按钮的默认提交事件
    })

    请求路由:

    from django.urls import path
    
    from . import views
    
    urlpatterns = [
        path(r'', views.index, name='index'),
        path(r'sdd/from_case/', views.from_case, name='from_case'),
    ]
    app_name = 'sdd'

    页面竖直滚动

    健康测评-体质测试页面

    每次点击当前li,页面会变长,但是滚动条不会自动向下滚动,所以每次都要手动向下拉,很烦人。

    想做一个效果:每次点击当前li,页面自动向下滚动。

    百度了怎么获取页面滚动条滚动的距离:

    $(window).scroll(function(){
        //console.log(window.pageYOffset);
        pos = window.pageYOffset;
    })

    知道了每次滚动的距离是多少就好办了,只要我每次点击当前li,只要让滚动条自动向下前进一定的距离就可以实现想要的效果了,那怎么设置滚动条的距离?

    百度:

    var autoGo = function (pos) {
        $("html,body").animate({ scrollTop: pos },speed);
    };

    页面每次滚东pos距离,pos的单位是像素【字符串】,speed代表滚动的速度以毫秒级为单位的【是个数值】

     

    具体代码:

    var pos = 0;
    $(window).scroll(function(){
        //console.log(window.pageYOffset);
        pos = window.pageYOffset;
    })
    
    var autoGo = function (pos) {
        $("html,body").animate({ scrollTop: pos },0);
    };
    
    //first代表第一次点击,第一次点击前进的距离多一些
    
    if(first == 0){
        first++;
        pos = pos + 356 + 'px';
    }else{
        pos = pos + 127 + 'px';
    }
    //console.log(pos);
    autoGo(pos);

    python web函数调用:与java类似

     

     

    form表单提交遇到的问题

    做表单提交时遇到的问题:在form上加onsubmit = "return check(this)",不进入check方法,check方法返回ture则提交表单,否则不提交。换了一种方式,使用submit按钮的onclick方法,但是有个要求就是submit按钮的id不能为"submit",否则报form.submit();is not a function

     

     

    django模板for循环和表单提交

    for循环中我需要获取当前的序号:

    {{forloop.counter0}}

    代表以0开始

    {{forloop.counter}}

    代表以1开始。

    for循环中使用if判断当前序号是奇数偶数:

    {% if item.importent == True %}
        {% if forloop.counter0|divisibleby:2 %}
            <li class="title">{{tent}}</li>
        {% else %}
            <li>{{tent}}</li>
        {% endif %}
    {% else %}
        <li>{{tent}}</li>
    {% endif %}

    3.form表单获取表单内input的值:

    var form = document.getElementById("myfrom");
    if(form.sex.value == ''){
        alert("请选择性别!");
        return false;
    }

    使用该form对象.input的name.value

     

    一个form表单提交的实例:

    <form action="/survey/survey_hys_result" method="post" id="myfrom">
    ******
    
    <input type="submit" id="sub" value="测试中...">
    </form>
    
    sub.onclick = function() {
        if(isLast < 59) {
            alert("请先完成测试");
            if(isLast == 0){
                pos = 0 + 'px';
                autoGo(pos);
            }else{
                pos = 356 + 127*isLast + 'px';
                autoGo(pos);
            }
            return false;
        }
        var form = document.getElementById("myfrom");
        if(form.sex.value == ''){
            alert("请选择性别!");
            return false;
        }
        if(form.age.value == ''){
            alert("请选择年龄!");
            return false;
        }
        form.submit();
        return ture;
    }

    django传输数据限制

    我在使用post传递dicm影像数据时遇到的问题:Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE,由于默认django允许post传递的数据量为2.5MB

    setting中可以使用如下:设置传递的数据量为5MB

    DATA_UPLOAD_MAX_MEMORY_SIZE = 5242880 

    django上传文件

    在属性upload_path中配置上传路径

    要在settings里配置media上传文件路径,当上传文件时它会自动在项目中创建/static_in_env/upload路径,上传的文件将放在upload/dcm下

    上传service:

    在这里说一下我的上传路径也必须要前端能访问,不然前端不能通过url拿到dcm文件,也百度了,也看小叶之前代码的配置了,才知到其实不用那么复杂。首先:由于我的上传路径是和实体类绑定的,所以我必须要使用MEDIA_ROOT

    实体属性绑定:


    上传路径的等于MEDIA_ROOT + dcm/。

    其次是前端访问dcm静态文件路径:

    直接配置:

    MEDIA_URL即可。然后在urls里配置:

    先要导入两个包,然后配置两个静态访问路径。前端访问方式:


    可以直接使用/upload/访问其下的文件

     

    参照网址:

    上传service代码:https://blog.csdn.net/wanpengsen4890/article/details/81914135

    有关django表单对象:https://www.cnblogs.com/zongfa/p/7709639.html

    media上传路径的配置https://www.cnblogs.com/yinxin/p/9076894.html

    MEDIA_ROOT, MEDIA_URL, STATIC_ROOT, STATIC_URL的介绍:

    https://blog.csdn.net/geerniya/article/details/78958243

     

     

    django返回ajax数据

    django返回页面并渲染模板

    django模板中使用富文本标签

    {{ if info.就诊.重点检查项目 }}
        <div class="describe-project">
            <p class="item-name">重点检查项目</p>
            <p class="item-content padding-l-20">
                {{ each info.就诊.重点检查项目 val key }}
                    {{@ val }}
                {{ /each }}
            </p>
         </div>
    {{ /if }}
    
    // 也可以直接在script中使用
    <script>
        console.log({{info}})
    </script>

    django的HttpRequest 

    由于在访问详情页面时我使用的传参方式是:


    如上,前端如下

    但是我拿到详情页后又要去处理这个dcm文件(split操作),所以我又要将这个dcm的id在传给split,我尝试了几种写法,如:

    结果都是404,我感觉可能有问题的就是这个<int:id>了,而且我这样写浏览器端的路径是相对路径:

    http://localhost:8000/12/detail/split

    http://localhost:8000/12/detail/12/split

    根本和我的url匹配不上,最后我先从浏览器端开始,使用绝对路径,所以我就用到了request对象,其document地址为:https://docs.djangoproject.com/en/2.1/ref/request-response/

    我的处理如下:


    这个即可以在后台获取传到前台也可以在前台使用{{ request.scheme }}和{{ request.get_host }}获取,我是在后台获取传到前台的

     

    我改变了方式,不在url的路径里传递参数了,因为我是异步请求,可以直接将id使用data传过去。这样就解决了所有问题。

     

     

    Django内置模板标签和过滤器

    针对于使用render返回的数据,如果在前台直接拿的话是需要转义和转成json对象的。

    def index(request):
        """
        患者病例系统的首页
        :param request:
        :return:
        """
        data = list(DICT_JYJC.objects.values())
        return render(request, 'index.html', {'list': data})

    script标签中:

    <script>
        var data = '{{ list }}';
        data = data.replace(/&#39;/g,'"');
        console.log(data);
        console.log(JSON.parse(data));
    </script>

    自己好久没用django了,也忘记了django有哪些模板标签了,使用模板标签的话,直接就可以遍历,并不需要多此一举在script里做处理。在此加一笔,记录。推荐好文

    <span class="fz-input">
        <input type="text" class="input-line"
               style=" 150px;text-align: center">
        <select>
            {% for foo in list %}
                <option>{{ foo.VAL }}</option>
            {% endfor %}
        </select>
    </span>

    Django自定义模板【过滤器】

    首先说说我自定义的普通for循环【遍历两个等长列表】:

    for(int i=0;i<list1.lenght;i++){
        print(list1[i]);
        print(list2[i]);
    }

    django模板中只有

    {% for txt in list %}
        {{ txt }}
    {%endfor%}

    的实现

    而此时我要遍历两个等长列表,麻烦来了,我无法直接使用forloop.count0作为列表的索引使用

    即:list[forloop.count0]不支持。

    查阅网上的做法基本没有,没办法,最后选择了自定义模板方法:

    1.在应用中创建templatetags文件夹,该文件夹下要包含一个_init_.py文件和一个存放你自定义模板方法的地方:

     

    图中:我app名字为survey,存放我自定义模板方法的地方为survey_dealfor.py。

    看一下survey_dealfor.py:

    from django import template
    
    register = template.Library()
    
    @register.filter(name='dfor')
    def dfor(index, list):
        print(index)
        print(list)
        return list[index]

    dfor方法传来两个参数,一个是索引,一个是列表,返回该列表在该索引处的值。

    然后在settings.py中:

    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',
                ],
                'libraries': {
                            'survey_dealfor': 'survey.templatetags.survey_dealfor',
                        }
            },
        },
    ]

    添加libraries配置项,survey_dealfor就是你马上即将要在html中load的名字,该名字对应着你自定义模板的路径。

    看一下html:

    {% for litext in item.selection %}
        <span>
            <a href="#question2" class="question-two-picture">
                <span class="picture-text">{{litext}}</span>
                <img class="img-content" src="/static/survey/images/{{ forloop.counter0|dfor:item.selectImg }}">
            </a>
        </span>
    {% endfor %}

    这样就ok了,然后你一定要重启一次服务才行。这样我实现了我想要的效果,没毛病。

     

    你可能会遇到问题看这里:

    https://stackoverflow.com/questions/40686201/django-1-10-1-my-templatetag-is-not-a-registered-tag-library-must-be-one-of/42881074

     

    Django中混合使用artTemplate

    由于django自带的模板标签语言和artTemplate有差异,如果直接在script里嵌入artTemplatedjango会不能识别而报错,要在django中使用artTemplate要加以下条件:

    <script id="temptab" type="text/html">
            {% verbatim %}
            {{ each list as v i }}
            <tr id="'{{ v.id }}'">
                <td>
                    {{if v.is_files}}
                        <a href="javascript:;" onclick="dir_detail('{{ v.id }}',1)">
                            <span class="glyphicon glyphicon-folder-close icon-dir" aria-hidden="true"></span>
                            <span class="fename">{{ v.name }}</span>
                        </a>
                    {{ else }}
                        <span class="glyphicon glyphicon-file" aria-hidden="true"></span>
                            {{ if v.dir_rank == 2 }}
                                <span class="fename"><a href="dcmDetail/?id={{ v.pid }}&flag=0">{{ v.name }}</a></span>
                            {{ else }}
                                <span class="fename"><a href="dcmDetail/?id={{ v.pid }}&flag=1">{{ v.name }}</a></span>
                            {{ /if }}
                    {{/if}}
                </td>
                <td class="feinfo">{{ v.info }}</td>
                <td>{{ v.time | dateFormat:'yyyy-MM-dd h:m:s' }}</td>
                <td>
                    {{ if v.dir_rank == 0 }}
                        <a href="javascript:;" data-toggle="modal" data-target=".edit-dir-modal"
                           onclick="editDir('{{ v.id }}','{{ v.name }}','{{ v.info }}')">
                            编辑
                        </a>
                        <a href="javascript:;" data-toggle="modal" data-target=".add-dir-modal"
                           onclick="addSecDir('{{ v.id }}','{{ v.name }}')">
                            创建子目录
                        </a>
                    {{ /if }}
                    {{ if v.dir_rank == 1 }}
                        <a href="javascript:;" data-toggle="modal" data-target=".add-file-modal"
                           onclick="addNewFiles('{{ v.id }}','{{ v.name }}')">
                            上传DCM文件
                        </a>
                        <a href="javascript:;" data-toggle="modal" data-target="#splitModal" data-keyboard="false"
                           data-backdrop="static" onclick="split('{{ v.id }}')">
                            分割
                        </a>
                    {{ /if }}
                    {{ if v.dir_rank == 2 }}
                        <a href="dcmDetail/?id={{ v.pid }}&flag=0">show</a>
                    {{ else if v.dir_rank == -3 }}
                        <a href="dcmDetail/?id={{ v.pid }}&flag=1">show</a>
                    {{ /if }}
                    {{ if v.dir_rank == 0 || v.dir_rank == 1 || v.dir_rank == -1 || v.dir_rank == -2 }}
                        <a href="javascript:;" onclick="del('{{ v.id }}',this)">
                            删除
                        </a>
                    {{ /if }}
                </td>
            </tr>
            {{ /each }}
            {% endverbatim %}
        </script>

    你要将你的artTemplate使用{% verbatim %}{% endverbatim %}包裹起来,这样django就不会编译这段代码,然后使用后台传递来的数据,将你的数据嵌入你写的模板中:

    $.ajax({
                type:'post',
                url:'dir_detail/',
                data:{id:id, flag:flag},
                dataType:'json',
                success:function(data) {
                    var list = [];
                    for (var i = 0;i<data.length;i++) {
                        var dt = data[i];
                        dt.fields.id = dt.pk;
                        list.push(dt.fields);
                    }
                    var content =  template('temptab',{'list':list});
                    $("#file_content").html(content);
                    if(list.length != 0) {
                        $(".pre-dir").data('id',list[0].pid);
                    }
                }
        });

    如上:使用template方法时,你必须指定一个json对象,‘list’对应模板的list,如果你直接传递list,像这样:

    var content =  template('temptab',list);

    你将得不到任何信息。

     

    Django--render()

    django携带数据返回页面,可直接将数据渲染到页面

    仔细看,你会发现使用render可以直接传递没有序列化的实体,而且他能够恰好的映射到模板上。而使用:

    HttpResponse时如果是传递普通的字符串json对象,可以直接上传,但是要上传实体时就要将实体序列化后才能上传,不然就报错,说不能上传没有序列化的数据。

     

     

    Django--local()

     

     

    日期格式处理

    实体日期类型:

    更改类型【dateTime.strftime】:

    django order_by

    如上:查询数据库,安装is_files和time两个字段排序,其中is_files是降序,time是升序。即:加个负号代表是降序,默认是使用升序

     

    django filter

    相当于:

    select * from db where name = 'split' and pid = '909218329989'

    shutil模块递归删除文件目录

    import shutil
    shutil.rmtree(path)

    Django 只查询单个字段

     

    https://www.jianshu.com/p/7c7645674ae0

     

    Django 查询结果返回前台出现' 或者 "

    解决方案:

    {{ data|safe }}

    Django 批量插入

    # save 补充条件:批量插入
            bd_bctj_list = []
            for o in other:
                bd_bctj = BD_BCTJ()
                bd_bctj.BLID = blid
                bd_bctj.JLID = jlid
                bd_bctj.ZZID = o['zzid']
                bd_bctj.ZZXXID = o['zzxxid']
                bd_bctj_list.append(bd_bctj)
            BD_BCTJ.objects.bulk_create(bd_bctj_list)

    Django 原生SQL

    import django
    from django.db import connection
    import logging
    import traceback
    logger = logging.getLogger("django")
    
    @staticmethod
    def execute(sql, params=None, _one=False, _dict=False):
        """
        执行一条SQL
        :param sql: example: 'select * from table where name = %s'
        :param params: sql参数
        :param _one: 默认使用fetchall,若_one=True则使用fetchone
        :param _dict: 封装成dict形式
        :return:
        """
        try:
            with connection.cursor() as cursor:
                cursor.execute(sql, params)
                if _one:
                    result = cursor.fetchone()
                else:
                    result = cursor.fetchall()
                if _dict:
                    col_names = [desc[0] for desc in cursor.description]
                    result = dict(zip(col_names, result))
        except django.db.DatabaseError as e:
            logger.error(traceback.format_exc())
            raise e
        return result
        
        
        
        
    # 如果在Python中和Mysql一起使用时,可以直接用下面方式 
    import MySQLdb   
    conn = getConnection(dbparams)
    cursor=conn.cursor(cursorclass = MySQLdb.cursors.DictCursor);
    vreturn=cursor.execute(sql)

    Django 事务回滚

    from django.db import transaction
    
    在需要使用事务的地方:
    if exist == False:
        # use transaction
        with transaction.atomic():
            # write files to dir
            dest = open(file_path, 'wb+')
            for chunk in f.chunks():
                dest.write(chunk)
            dest.close()
            # get dcm rank
            dcm_rank = -1
            image = sitk.ReadImage(file_path)
            keys = image.GetMetaDataKeys()
            for key in keys:
                if key == '0020|0013':
                    dcm_rank = image.GetMetaData(key)
            # write db
            file = createFiles(
                {'pid': dir_id, 'name': f.name, 'info': filesinfo, 'dir_rank': 3, 'dcm_rank': dcm_rank,
                 'is_files': False, 'path': dir.path + f.name})
            file.save()
    else:
        ...

    如上我需要将上传dcm文件和创建dcm实体插入数据库这两个需要同步进行,添加事务只需要使用:

    with transaction.atomic():
        #在这里写需要同步的东西

    Django url传递参数

    一个参数:

    多个参数使用传统方式传递:

    使用GET.get方式获取

     

    更多参数:

    https://www.cnblogs.com/lixiang1013/p/7748156.html

     

     

    Django 生成和执行requirements.txt

    生成【在manage.py同目录下执行】:

    pip freeze > requirements.txt

    执行【在manage.py同目录下执行】:

    pip install -r requirements.txt

    Django 使用Oracle11g遇到的坑

    参考链接:https://www.jianshu.com/p/440c726cc516

    1:

    Django要使用oracle首先要去下载对应python版本和操作系统的oracle的驱动(cx_Oracle),由于当前我使用的Python版本是3.6.6服务器oracle版本是11g,查阅官网关于数据库支持这块,发现支持oracle11g的django版本在2.0以下,如果是2.0以上会报错cx_Oracle.DatabaseError: ORA-02000: missing ALWAYS keyword】,2.0只支持oracle12c极其以上版本,没办法我只好更换了我的Django版本为低版本。然后我在pypi官网上翻找了cx_Oracle【https://pypi.org/project/cx-Oracle/7.2.3/#files】驱动历史版本,发现只有cx-Oracle==5.3支持我当下情况:

    于是我使用pip安装,

    pip install cx-Oracle==5.3

    结果报了一个奇怪的错误,没办法我只好手动的去下载上图我标记的那个文件,下载后手动安装时我又遇到了一个特别恶心的问题就是这个exe安装时会自动读取Python的安装路径,但是由于我使用的是Anaconda去管理的Python版本,所以这个exe根本读取不了我的Python安装路径,而且还不能自己手动输入自己的Python安装路径,没办法,我试图在环境变量里配置Anaconda中已经下载的python3.6.5,再次安装这个exe还是不行!没办法,我只好老老实实的去官网上在下载一个Python3.6.6安装包,在本地安装了一下并配置好环境变量,在安装那个exe文件,问题解决了。到此我也仅仅只是安装了oracle的数据库驱动。

    接下来开始下载对应服务器的oracle客户端instantclient_11_2,把其中的oci.dll、oraocci11.dll、oraociei11.dll三个文件拷贝到python3.6.6环境下lib/sit-packages目录下

    下面我开始切换我项目的环境,由于之前我项目里使用的是Anaconda里的py365创建的虚拟环境,现在oracle的驱动安装在本地Python3.6.6中了,所以要将项目环境切换到刚安装的Python3.6.6里,经过一番折腾(还好项目不大),终于切换完了,我写了一个测试文件,测试一下这个cx_Oracle驱动能不能使用:

    import cx_Oracle
    
    # Create your tests here.
    if __name__ == '__main__':
        '''Hello cx_Oracle示例:
        conn = cx_Oracle.connect("username/pwd@localhost/dbname")
        cur = conn.cursor()
        try:
             #cur.execute("insert into bd_hzbl values(3,1,22,'a','b','c','d','e','f','g',null,null)")
            #conn.commit()
            
             cur.execute('select * from bd_hzbl')
             data = cur.fetchall()
             print(data)
        finally:
            cur.close()
            conn.close()

    还好还好,对于插入和查询都没问题,这下我就放心了,开始在我的项目里使用oracle了【在此之前我下载了oracle的客户端64位的并配置好了环境变量,因为我要连接服务器上的数据库】。

    常用操作:

    #第一步:创建基本model:
    
    python manage.py migrate
    
    #第二步:初始化自己的model
    
    python manage.py makemigrations TestModel
    
    #第二步:初始化数据库表
    
    python manage.py migrate TsetModel

    如果以上两步出现了问题,最好看看你有没有oracle客户端,有没有oracle配置环境变量。

    然后校验我们的model:

    python manage.py inspectdb 表名 > aaa.py

    一路坎坷,各种百度解决问题,现在到了开始在项目里使用它了,我创建了一个简单的表单,和一个model:

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    '实体'
    from django.db import models
    
    # 患者病例
    class BD_HZBL(models.Model):
         ID = models.AutoField(primary_key=True)
        XB = models.IntegerField()  # --性别 0-男 1-女
        NL = models.IntegerField()  # --年龄
        TSSQ = models.CharField(max_length=2)  # --特殊时期
        ZS = models.CharField(max_length=200)  # --主诉
        XBS = models.CharField(max_length=200)  # --现病史
        JWS = models.CharField(max_length=200)  # --既往史
        TGJC = models.CharField(max_length=200)  # --体格检查
        FZJC = models.CharField(max_length=200)  # --辅助检查
        BZ = models.CharField(max_length=200)  # --备注
        CJSJ = models.DateTimeField()  # --创建时间 auto_now_add=True
        XGSJ = models.DateTimeField()  # --修改时间 auto_now=True
    
        class Meta:
            db_table = 'BD_HZBL'

    然后请求提交表单,在处理器中将这个表单数据赋值给实体属性,然后save实体,这是一个正常的操作:

    # 保存一个实体类
    bd_hzbl = BD_HZBL()
    bd_hzbl.ID = 3
    bd_hzbl.XB = 1  # sex
    bd_hzbl.NL = 23  # age
    bd_hzbl.TSSQ = 'a'  # rs + ',' + br
    bd_hzbl.ZS = 'b'  # zs
    bd_hzbl.XBS = 'c'  # xbs
    bd_hzbl.JWS = 'd'  # jws
    bd_hzbl.TGJC = 'e'  # tgjc
    bd_hzbl.FZJC = 'f'  # jcxm
    bd_hzbl.BZ = 'g'  # jcjg
    bd_hzbl.CJSJ = timezone.now()
    bd_hzbl.XGSJ = timezone.now()
    bd_hzbl.save()

    但是在项目里就不正常了,报了一个错误:

    django.db.utils.DatabaseError: OCI-22061: invalid format text [999999999999999999999999999999999999999999999999999999999999999]

    但是我如果使用:

    all = BD_HZBL.objects.all()

    它有神奇的给我返回了三个数据【我测试cx-Oracle时插入的三个】。这明显的是说明我的实体类写的肯定有一些问题的!

    到此,我彻底卡住了,网上关于这个错误的问题寥寥无几,最后我在国外的一篇文章上找到了擦边答案:https://sourceforge.net/p/cx-oracle/mailman/message/26209197/

    这篇文章讲的是关于我oracle字符集编码的问题,但是最后我也尝试设置我本地客户端字符集编码了(和服务器同步),最后还是没能解决。

    我开始针对我的字段进行测试,我尝试删除所有字段(并重新生成表),仅仅保留主键字段,奇迹的是我竟然save成功了!!!数据库里出现了ID字段为1的数据,这令我欣喜若狂,接下来我又开放了一个IntegerFiled字段(重生表),不幸的是又出现了那个OCI-22061的错误!我屏蔽IntegerField字段开发CharFiled又成功插入了!我赶紧跑到django1.11官网上查找有关IntegerField的说明,并没有我所期望的信息,至此我知道了使用IntegerField是不行的,但是我没有更好的办法了,官网上说能用,但是在我这不能用。无奈,我将IntergerField字段都改成了CharField,这个问题算是心有不快的勉强解决了。

     

     

     

    Django 启动时执行任务

    官网介绍:https://django.readthedocs.io/en/latest/ref/applications.html

    网友使用:http://www.cnblogs.com/xjmlove/p/10087053.html

    打印两次问题:https://stackoverflow.com/questions/37441564/redefinition-of-appconfig-ready

     

    如果你想在你的应用程序启动时执行某件事,django提供了一个很好的方式就是在你的app应用程序里的apps.py程序里重写AppConfig超类的ready()方法

    看到官网的说明我就直接尝试了重写ready()方法,如下:

    # sdd/apps.py
    from django.apps import AppConfig
    from django.utils.module_loading import autodiscover_modules
    
    
    class SddConfig(AppConfig):
        name = 'sdd'
    
        def ready(self):
            print(1)
            autodiscover_modules("***.py") # 用于启动时执行某个文件,***.py和apps.py同目录下

    然后启动django,并没有执行我的ready()方法,百思不得其解,去网上查找也没有相关的说明,我打断点压根就不跳到我的断点处,虽然我可以用其他方式去在django启动时执行我的任务(就是在sdd/views.py中的开始处写我的任务,或在urls中写我的任务),但是我有洁癖,感觉那样很不爽。抱着一定要解决这个问题的态度,又跑去官网查看,无意间我往上翻了翻,哦!原来不仅要重写ready()方法还要有一些其他东西要配置!!!

    按照官网说的,我在我的app下(即sdd),新建了一个__init__.py文件,在其中添加一行如下:

    default_app_config = 'sdd.apps.SddConfig'

    代码目录看下图:

    然后再次启动django,问题解决,控制台打印出了两个1,为什么会打印出两个1我也大概知道:

    python manage.py runserver --noreload

    至此这个问题已经解决了。

     

     

    Django 如何优雅的停止

    终止uwsgi

    自强学堂关于发送给进程的信号

     

     

    关于跨域请求session的问题

    先读

     

     

    关于拦截器中修改response问题

    在拦截器中修改response:

    class ParamsMiddleWare(MiddlewareMixin):
        """
        AOP:处理请求参数
        """
    
        def process_response(self, request, response):
        """
        AOP:拦截response,使用AES加密返回状态码为200的结果
        :param request:
        :return:
        """
        if request.path.startswith('/api/'):
            if response.status_code == 200:
                resp = HttpResponse(content=encrypt_data(KEY.encode('utf-8'), response.content.decode('utf-8')),
                                    content_type='text/plain')
                return resp
        return response

    如上代码所属,我在拦截器中重新定义了一个新的response返回,这一切看起来没什么问题,在django的拦截器中这么定义也很正常,而且我在postman里测试也一切都没问题,有问题的是在前端axios的全局拦截器里竟然在错误的回调函数里返回给我一个如下错误:

    Failed to load resource: net::ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH
    Uncaught (in promise) Error: Network Error
        at createError (webpack-internal:///./node_modules/axios/lib/core/createError.js:16)
        at XMLHttpRequest.handleError (webpack-internal:///./node_modules/axios/lib/adapters/xhr.js:83)

    这就让我很郁闷了啊,如果我不新建一个HttpResponse返回,之间用参数中的response返回,axios能拿到数据且不会报任何错误。细想这肯定是因为两个response之间有差异导致的,到底有什么差异?我在debug发现二者的_headers属性不一样,于是我尝试之间将参数里的response的_headers赋值给新建的HttpResponse对象,这导致Django无法正常返回响应。我向肯定是我的操作姿势不对,在官网API中找到了一个可以设置header的方法

    resp.setdefault(header, temp)
    
    # resp.setdefault('content-type', 'application')

    这个方法让我无比的吐槽,且看一下源码部分:

    def __setitem__(self, header, value):
        header = self._convert_to_charset(header, 'ascii')
        value = self._convert_to_charset(value, 'latin-1', mime_encode=True)
        self._headers[header.lower()] = (header, value)
    
    
    def setdefault(self, key, value):
        """Set a header unless it has already been set."""
        if key not in self:
            self[key] = value

    调用setdefault没啥问题,问题出在__setitem__上,这个方法竟然将我设置的header的值组合成了(header,value),这尼玛,导致我新建的response和参数里的response不一样!

     

    前进时,请别遗忘了身后的脚印。
  • 相关阅读:
    virtualbox使用相关问题
    mac os中的一些快捷键使用及基础软件安装
    U盘安装CentOS7
    Netbeans8下 Weblogic EJB案例
    Linux Weblogic 数据源 TimesTen配置
    JDBC操作TimesTen
    Red Hat TimesTen安装记录
    使用Protractor进行AngularJS e2e测试案例
    基于Karma和Jasmine的AngularJS测试
    protractor protractor.conf.js [launcher] Process exited with error code 1 undefined:1190
  • 原文地址:https://www.cnblogs.com/liudaihuablogs/p/13463174.html
Copyright © 2011-2022 走看看