利用Django做项目遇到的坑

引言

最近在用Django开发一个商城项目,第一次用这种语言来进行开发,凭借自己薄弱的MVC(在Django叫MTV)知识,以及不断地查Stack Overflow(感觉国内相关的博客比Java少多了),还是勉强地开发出来了,其实最科学的方法是查Django的开发手册(但是我英文不太好hhh),现在谈谈自己踩过的坑。

1、在models中filter和get的区别

当我们要从某个模型(model)中取出特定条件的数据的时候,可以采用这两种方法

 queryset = models.Commodity.objects.filter(cid=com_id)

v = models.Village.objects.get(vid=vid)

先观察他们的结果:

他们的不同之处在于:filter()获得的是一个QuerySet,当符合条件的有多条数据的话,也会将这些数据全部存入QuerySeet,当数据不存在,返回空的QuerySet

缺点:要取出里面的对象的值非常麻烦

而get()获得的是一个实体对象,当符合条件的有多条数据的话或者数据不存在,会报错,

优点:可以直接取出对象的值,如 vid = v.vid

2、simplejson输出的中文被转成ASCII码的解决办法

由于后端的接口都是通过JSON来返回数据的,所以Python中的simplejson工具显得十分重要,但是初次使用出现这种情况

这是由于中文被转化成ASCII码了,所有我们的结果中含有中文的时候,请记得加上

json_data = simplejson.dumps(queryset, ensure_ascii=False)

3、当接口用POST方法的时候,用POSTMAN等工具调试总是提示“403”错误

出现这样的问题,其实是因为Django有自己的csrf防御机制,我们可以假设这样一个情景:

1.用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;

2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;

3.用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;

4.网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;

5.浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

好了跑题了,我们那我们要进行测试应该怎么解决这个问题呢?就是在方法前加上注解

@csrf_exempt,来取消csrf的防御

4、当我们要取出values_list里面的内容要怎么做

olist=list(models.Order.objects.filter(user_id=openid).values_list('oid','total','date','address_id'))

我已经提前把它转化为list,可以通过断点看出:

它的外部是个list,内部是个tuple(元组),根据数据结构的知识(不懂百度下),我们可以遍历把他们都取出来,具体代码如下:

olen = len(olist)
    for i in range(olen):
        oid = olist[i][0]
        total = olist[i][1]
        date = olist[i][2]
        address_id = olist[i][3]

注意:循环条件不能写成range[0:olen],否则会报错:“olen不是可以遍历的”

结果如下:

总结:value_list获得的就是一个里面分别装有tuple的queryset

5、获取request中POST方法传来的JSON

之前想通过表单的方式传来数据,但是一直不成功,代码如下:

oid = request.POST.get("oid")

后来决定用JSON来传输,也比较符合现在互联网的规则,那么后台怎么解析呢,主要还是用simplejson,具体代码如下,仅供参考:

 try:
        if request.method == 'POST':
            req = simplejson.loads(request.body)
            '''
            从JSON数组中获取一系列的参数
            '''
            openid = req['openid']
            area = req['area']
            detail = req['detail']
            name = req['name']
            phone = req['phone']
 except Exception:
        import sys
        info = "%s || %s" % (sys.exc_info()[0], sys.exc_info()[1])
 dict['message'] = info
 dict['create_at'] = str(ctime())
 json = simplejson.dumps(dict)            

6、注意Python2.7和Python3.5的包

举一个简单点的例子,当我用到了urlib来进行网络连接请求的时候,由于本机用了Python3.5,服务器的却是Python2.7(蛋疼),然后部署上去就有各种bug了,在Python2.7中,代码如下:

def connect(url):
    req = urllib2.Request(url)
    result = urllib2.urlopen(req)
    res = result.read()
    return res

在Python3.5中,代码如下:

def connect(url):
    req = urllib.request.Request(url)
    result = urllib.request.urlopen(req)
    res = result.read()
    return res

7、输出的JSON带有\

这个问题和前面的中文乱码不一样,这里要搞清楚simplejson的最基础一点:dumps方法是将元素转换成一个JSON格式的str(字符串),而loads方法则是读取json使之变成一个dict对象

下面请看代码:

 json_add = simplejson.dumps({"area": area, "detail": detail, "name": name,"phone": phone},ensure_ascii=False)
 aresult = json.loads(json_add)

对于dict对象,我们可以用append方法来进行字典元素的拼接

posted @ 2017-08-23 21:47  scnu_lyp  阅读(333)  评论(0编辑  收藏  举报