Django项目笔记:sessions处理以及复杂对象序列化
前言:一点题外话
我发现,不更新博客的时候,不是非常忙,就是效率非常低。最近没怎么更新博客,原因是第二种= =。惭愧惭愧。
今天效率出奇的高,一天时间把PassNote后端的接口全部写完了,Django很好用,不过实际项目中还是有些框架不能实现的功能需要解决的,我比较喜欢造轮子,不过为了保证效率,还是尽量用现成的工具,减少不必要的折腾。
关于PassNote
之前应该在博客有说过,这是一个密码管理器,用于加密保存各种网站帐号和密码,还可以生成高强度的密码。
项目主页:https://deali-axy.github.io/PassNote/ 了解一下。
不过这个只是一个桌面版软件,也没有云备份功能,所以一直想找时间开发一个跨平台的版本,一直拖延着,等到今天才开始写。
Django的session处理
session简单说就是把cookie拿到服务器端去保存,然后客户端通过服务器返回的id作为session标识。
session框架让你存储和获取访问者的数据信息,这些信息保存在服务器上(默认是数据库中),以 cookies 的方式发送和获取一个包含 session ID的值,并不是用cookies传递数据本身。
Django中使用session
启用session
编辑settings.py。
在MIDDLEWARE_CLASSES中添加:
'django.contrib.sessions.middleware.SessionMiddleware',
在INSTALLED_APPS中添加:
'django.contrib.sessions',
在view中使用
# 创建或修改 session:
request.session[key] = value
# 获取 session:
request.session.get(key,default=None)
# 删除 session
del request.session[key] # 不存在时报错
更多session的用法可以参考官方文档:https://docs.djangoproject.com/en/2.0/topics/http/sessions/
关于复杂对象序列化
对于序列化 Django 数据的解决方案已经有以下几种:
django.core.serializers
Django内建序列化器, 它可以序列化Django model query set 但无法直接序列化单独的Django model数据。如果你的model里含有混合数据 , 这个序列化器同样无法使用(如果你想直接使用序列化数据). 除此之外, 如果你想直接把序列化数据返回给用户,显然它包含了很多敏感及对用户无用对信息。
QuerySet.values()
和上面一样, QuerySet.values() 同样没法工作如果你的model里有 DateTimeField 或者其他特殊的 Field 以及额外数据。
django-rest-framework serializers
django-rest-framework 是一个可以帮助你快速构建 REST API 的强力框架。 他拥有完善的序列化器,但在使用之前你需要花费一些时间入门, 并学习 cbv 的开发方式, 对于有时间需求的项目显然这不是最好的解决方案。
简单说就是Django里面的几种现成方案不是功能不够强大就是学习成本高,正当我要自己造轮子的时候,我找到一个方便的解决方案,所以为了节省时间,立刻放弃了自己造轮子的计划。
项目地址:https://github.com/bluedazzle/django-simple-serializer 了解一下。
不过在实际使用的时候又有一个问题,就是序列化QuerySet的时候,如果包含AutoField的话就报错:'AutoField' object has no attribute 'rel'
有点坑啊,好不容易找到个好用的工具不用自己造轮子,突然发现这工具有问题,我还要帮它填坑??
好吧,没办法,只能出手了,由于代码没有注释,我也没那么多时间去研究具体问题出在哪里,所以就哪里出错改哪里。刚才也在github上给作者发了issue了。
修改了 Serializer 文件的data_inspect函数。
代码如下,加了一个rel属性判断。
def data_inspect(self, data, extra=None):
if isinstance(data, (QuerySet, Page, list)):
convert_data = []
if extra:
for i, obj in enumerate(data):
convert_data.append(self.data_inspect(obj, extra.get(
**{self.through_fields[0]: obj, self.through_fields[1]: self.source_field})))
else:
for obj in data:
convert_data.append(self.data_inspect(obj))
return convert_data
elif isinstance(data, models.Model):
obj_dict = {}
concrete_model = data._meta.concrete_model
for field in concrete_model._meta.local_fields:
# 检查 field 是否存在 rel 这个属性,为'AutoField' object has no attribute 'rel'错误填坑
if hasattr(field, 'rel'):
if field.rel is None:
if self.check_attr(field.name) and hasattr(data, field.name):
obj_dict[field.name] = self.data_inspect(getattr(data, field.name))
else:
if self.check_attr(field.name) and self.foreign:
obj_dict[field.name] = self.data_inspect(getattr(data, field.name))
else:
if self.check_attr(field.name) and hasattr(data, field.name):
obj_dict[field.name] = self.data_inspect(getattr(data, field.name))
for field in concrete_model._meta.many_to_many:
if self.check_attr(field.name) and self.many:
obj_dict[field.name] = self.data_inspect(getattr(data, field.name))
for k, v in data.__dict__.items():
if not str(k).startswith('_') and k not in obj_dict.keys() and self.check_attr(k):
obj_dict[k] = self.data_inspect(v)
if extra:
for field in extra._meta.concrete_model._meta.local_fields:
if field.name not in obj_dict.keys() and field.name not in self.through_fields:
if field.rel is None:
if self.check_attr(field.name) and hasattr(extra, field.name):
obj_dict[field.name] = self.data_inspect(getattr(extra, field.name))
else:
if self.check_attr(field.name) and self.foreign:
obj_dict[field.name] = self.data_inspect(getattr(extra, field.name))
return obj_dict
elif isinstance(data, manager.Manager):
through_list = data.through._meta.concrete_model._meta.local_fields
through_data = data.through._default_manager
self.through_fields = [data.target_field.name, data.source_field.name]
self.source_field = data.instance
if len(through_list) > 3 and self.through:
return self.data_inspect(data.all(), through_data)
else:
return self.data_inspect(data.all())
elif isinstance(data, (datetime.datetime, datetime.date, datetime.time)):
return self.time_func(data)
elif isinstance(data, (ImageFieldFile, FileField)):
return data.url if data.url else data.path
elif isinstance(data, Decimal):
return float(data)
elif isinstance(data, dict):
obj_dict = {}
if self._dict_check:
for k, v in data.items():
obj_dict[k] = self.data_inspect(v)
else:
for k, v in data.items():
if self.check_attr(k):
obj_dict[k] = self.data_inspect(v)
return obj_dict
elif isinstance(data, (str, bool, float, int)):
return data
else:
return None
测试了一下,可以正常使用,那就暂时这样吧,虽然有点“hack编程”的感觉,hhh
End
以上就是项目笔记的全部内容了,新版的PassNote和之前一样,在开发完成之后,会全部开源,这次是准备做移动、桌面、小程序多端跨平台的啦,有兴趣的朋友可以关注一下哈~
国际惯例,附截图一张。

About

了解更多有趣的操作请关注我的微信公众号:DealiAxy
每一篇文章都在我的博客有收录:blog.deali.cn
Django项目笔记:sessions处理以及复杂对象序列化的更多相关文章
- Django 项目笔记
Django 环境的搭建 Django 安装 pip install django==2.1.4 Django 创建项目 django-admin startproject mysite Django ...
- 笔记:I/O流-对象序列化
Java 语言支持一种称为对象序列化(Object Serialization)的非常通用的机制,可以将任何对象写入到流中,并在之后将其读回,首先需要支持对象序列化的类,必须继承与 Serializa ...
- 吴裕雄--天生自然JAVAIO操作学习笔记:字符编码与对象序列化
public class CharSetDemo01{ public static void main(String args[]){ System.out.println("系统默认编码: ...
- Django商城项目笔记No.2项目准备工作
Django商城项目笔记No.2项目准备工作 接着上篇开始,创建好工程之后,随之而来的是怎么配置工程,这篇文章记录如何进行相关的配置 1.pycharm打开工程,进行相关的配置 通过pycharm打开 ...
- Django 创建项目笔记
基本命令 mkdir mysite # 创建项目目录,常取名mysite cd mysite virtualenv env # env\Scripts\activate.bat # Win pip i ...
- Django商城项目笔记No.12用户部分-QQ登录2获取QQ用户openid
Django商城项目笔记No.12用户部分-QQ登录2获取QQ用户openid 上一步获取QQ登录网址之后,测试登录之后本该跳转到这个界面 但是报错了: 新建oauth_callback.html & ...
- Django商城项目笔记No.5用户部分-注册接口-短信验证码
Django商城项目笔记No.4用户部分-注册接口-短信验证码 短信验证码也保存在redis里(sms_code_15101234567) 在views中新增SMSCodeView类视图,并且写出步骤 ...
- Django商城项目笔记No.4用户部分-注册接口-图片验证码
Django商城项目笔记No.4用户部分-注册接口-图片验证码 1.首先分析注册业务接口 1.1.分析可得,至少这么几个接口 图片验证码 短信验证码 用户名是否存在 手机号是否存在 整体注册接口 图片 ...
- Django商城项目笔记No.3用户部分-用户模型类
Django商城项目笔记No.3用户部分-用户模型类 Django提供了认证系统,文档资料https://yiyibooks.cn/xx/Django_1.11.6/topics/auth/index ...
随机推荐
- 在Centos 7中使用 Docker搭建MySQL异地双向复制环境
(0)一些准备操作: Centos安装好之后(这里使用的是vm虚拟机) 将当前用户添加到sudoers中: su root vim /etc/sudoers 找到 root ALL=(ALL) ALL ...
- Bitnami 2015
WordPress WordPress is one of the world's most popular web publishing platforms for building blogs a ...
- Android Volley框架的使用(四)图片的三级缓存策略(内存LruCache+磁盘DiskLruCache+网络Volley)
在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价——流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...
- 使用UnityVS1.8.2搭配VS2013进行Unity3D代码调试(下载+安装+使用+问题解决)
http://blog.dou.li/UnityVS1_8_2-VS2013.html 备整合UnityVS1.8.2和VS2013调试Unity3D代码,安装后会有些问题无法调试,详情继续往下看. ...
- spring--百度百科
Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development a ...
- EXTJS4自学手册——组合图像
Ext.create('Ext.panel.Panel', { title: '组合图像', renderTo: 'ComplexDiagram', items: [{ xtype: 'button' ...
- HDU 4925 Apple Tree(推理)
HDU 4925 Apple Tree 题目链接 题意:给一个m*n矩阵种树,每一个位置能够选择种树或者施肥,假设种上去的位置就不能施肥,假设施肥则能让周围果树产量乘2.问最大收益 思路:推理得到肯定 ...
- 阿里云dataworks数据工场用户使用子账号
如果您是第一次使用子账号登录数加平台和使用DataWorks,您需要获知以下内容: 该子账号所属主账号的企业别名. 该子账号的用户名和密码. 该子账号的AccessKey ID和AccessKey S ...
- 用户自定义类型《lua程序设计》 28章 笔记
本实例实现一种很简单的类型------布尔数组.C语言可以实现将每个布尔值存储在一个bit中,从而减少内存用量. 必须的一些宏 Code Snippet #defineBITS_PER_WORD (C ...
- 二维数组,锯齿数组和集合 C# 一维数组、二维数组(矩形数组)、交错数组(锯齿数组)的使用 C# 数组、多维数组(矩形数组)、锯齿数组(交叉数组)
二维数组,锯齿数组和集合 一.二维数组 二维数组:一维数组----豆角二维数组----表格 定义:1.一维数组:数据类型[] 数组变量名 = new 数据类型[数组长度];数据类型[] 数组变量名 = ...