博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
那些在django开发中遇到的坑
阅读量:6273 次
发布时间:2019-06-22

本文共 5252 字,大约阅读时间需要 17 分钟。

1. 关于csrf错误

CSRF(Cross-site request forgery)跨站请求伪造,也被称为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。

django中自带了防止CSRF攻击的手段,在form表单的action属性中,GET时不需要CSRF认证,而POST时需要。

一般而言,有两种解决办法:

① 启用csrf认证

• 在settings.py中启用中间件django.middleware.csrf.CsrfViewMiddleware

• 在views.py的render_to_response中,用RequestContext代替默认的Context,如下:

return render_to_response('a.html', data, context_instance=RequestContext(request, processors=[my_fun])) 

注:若想要重定向到一个action,则用HttpResponseRedirect

• 在模板文件中的 form 表单内添加 {% csrf_token %} 

② 关闭csrf认证

• 注释掉django.middleware.csrf.CsrfViewMiddleware即可

2. 后台传列表或者字典给js函数

这里容易遇到两个难题,一是中文会显示成unicode形式,二是引号会被转义,使得js函数出错

① 无论是字典还是列表,传给js都可以用json来处理:

import jsontest_dict = {    "weather": ["sun", "rainy", "windy"],    "mood": ["happy", "sad"]}json_str = json.dumps(test_dict, ensure_ascii=False)
View Code

注:其中的ensure属性是为了解决中文编码问题

② 在django中有专门禁止转义的方式,只需在js函数用标签围住相关代码块即可:

View Code

 3. 文件上传与下载

进行文件上传的时候我遇到很多错误,以下是简单的总结:

• 在form中方法必须问POST

• 在form中要加入:enctype="multipart/form-data"

• 后台用name属性接受前端的文件,以下为一种简单接受文件的写法:

myfile = request.FILES.get("file_name", None)if myfile != None:    des_dir = "/home/me/path/filename"    des_file = open(des_dir, 'wb+')        for chunk in myfile.chunks():        des_file.write(chunk)    des_file.close()
View Code 

文件下载则相对容易很多,以excel为例:

def write_excel():    #返回未保存的workbook    pass    def main_process(request):    response = HttpResponse(content_type='application/vnd.ms-excel')    response['Content-Disposition'] = 'attachment; filename=test.xlsx'    wb = write_excel()    wb.save(response)    return response
View Code

另外提供一个js获取文件后缀名的函数:

View Code

 4. python跨目录imprt模块

之前我写了一些模块,在别的目录下,想引用它们却一直出错,找了一些资料,总结了几个实用的Tips:

① 若被引用的模版在更低的目录中,如子目录(sub_dir),则需要在该子目录中建立__init__.py的空文件,则可以直接在文件中:

 import sub_dir.model_name 

② 若其在父目录,则需要:

import syssys.path.append("..") import model_name
View Code

 5. 后台获取前端select multiple的数据

前端代码如下:

View Code

  后台只需要执行(若是GET方法):

 select = request.GET.get("select_str", "") 

注:有时候用到getElementsByName的时候,需要主要得到的是一个数组,因为html中名字可以出现多次

6. 善于使用logging模块

① django中在settings.py中有个LOGGING的配置

LOGGING = {    'version': 1,    'disable_existing_loggers': False,    'filters': {        'require_debug_true': {            '()': 'django.utils.log.RequireDebugTrue',        }, # 针对 DEBUG = True 的情况    },    'formatters': {        'standard': {            'format': '%(levelname)s %(asctime)s %(pathname)s %(filename)s %(module)s %(funcName)s %(lineno)d: %(message)s'        }, # 对日志信息进行格式化        # INFO 2016-09-03 16:25:20,067 /home/ubuntu/mysite/views.py views.py views get 29: some info...    },    'handlers': {        'mail_admins': {            'level': 'ERROR',            'class': 'django.utils.log.AdminEmailHandler',             'formatter':'standard'        },        'file_handler': {             'level': 'DEBUG',             'class': 'logging.handlers.TimedRotatingFileHandler',             'filename': '/tmp/byod/byodadmin/byod.admin.log',             'formatter':'standard'        }, # 用于文件输出        'console':{            'level': 'INFO',            'filters': ['require_debug_true'],            'class': 'logging.StreamHandler',            'formatter': 'standard'        },    },    'loggers': {        'django': {            'handlers' :['file_handler', 'console'],            'level':'DEBUG',            'propagate': True # 是否继承父类的log信息        }, # handlers 来自于上面的 handlers 定义的内容        'django.request': {            'handlers': ['mail_admins'],            'level': 'ERROR',            'propagate': False,        },    }}
View Code

 重要的是handlers和loggers,handler定义了log文件所在位置,而一个logger可以将多个handler加入其中,我们在代码中使用只需:

import logginglogger = logging.getLogger("django") # 为loggers中定义的名称logger.info("some info...")
View Code

② 不使用django中的配置,直接封装成一个函数:

def initRotateLog(log_file="/path/name.log" , log_name="" , level=logging.DEBUG, max_bytes=100*1024*1024 , backup_count = 5 ):    handler = logging.handlers.RotatingFileHandler(log_file, max_bytes, backupCount)    fmt = '...' #自己去查相关资料    formatter = logging.Formatter(fmt)       handler.setFormatter(formatter)          logger = logging.getLogger(log_name)        logger.addHandler(handler)               logger.setLevel(log_level)    return logger
View Code

 使用的时候直接这样用:

from ... import  * #自己引入那个函数模块logger  = initRotate("/path/somepath/file.log")logger.info("lalala")
View Code

 7. xlwt的坑

在将大量数据(超过10w)写入到excel中,xlwt让我痛苦不堪,因为xlwt只支持写到的记录为65535条,多了便需要新建一个sheet或者重新写一个文件,但是我还是想直接写在一页,这个时候,我发现了另外一个模块:openpyxl()

怎么安装就不说了,很容易,这里介绍一下它的很常见的用法:

from openpyxl import load_workbook #读from openpyxl import Workbook #写#读的方法workbook = load_workbook(file_name)sheet1 = workbook.active #正在活动的sheet#遍历得到每行第一个单元格的值for row in sheet1.rows:    cell = row[0].value    #写的方法workbook = Workbook()sheet1 = workbook.activesheet1.title = "Sheet1"#写入100行100列数据,全是1for row_index in range(1, 101):    for col_index in range(1, 101):        sheet1.cell(row=row_index, column=col_index).value = 1#写入文件workbook.save(file_name)
View Code

8. 关于datetimepicker的使用

官方的datetimepicker貌似能够显示秒,但是那个秒不能用户操纵,于是我找了好久,找到一个包,里面有js和css等文件,还有一个demo.html的demo文件,效果如下:

插入一个示例代码:

    
datetimepicker示例
View Code

这个包的下载地址在这里,!

 

  未完待续...

转载于:https://www.cnblogs.com/vachester/p/7224572.html

你可能感兴趣的文章
控制台程序隐藏方法总结(四种)
查看>>
nginx负载均衡
查看>>
企业能源管理系统的基本要求和主要内容
查看>>
JAVA基础学习之-AQS的实现原理分析
查看>>
IT兄弟连 JavaWeb教程 监听器4
查看>>
[喵咪BELK实战(3)] logstash+filebeat搭建
查看>>
线程中无法注入bean
查看>>
jetty的xml配置文件
查看>>
Hyper-V:虚拟网络配置
查看>>
按位运算符操作
查看>>
java8对接口的改变
查看>>
springboot中使用filter时注入bean为null的解决办法
查看>>
唠唠SE的IO-04——缓冲输入输出流
查看>>
hive join 数据倾斜 真实案例
查看>>
Object-C代码练习【文件管理练习(每秒写入一个时间到文件)】
查看>>
Redis列表
查看>>
文件查找工具之find命令详解
查看>>
linux命令 — lsof 查看进程打开那些文件 或者 查看文件给那个进程使用
查看>>
PHP+Swoole及时通讯
查看>>
centos安装图形
查看>>