Django Project Notes: Session Handling and Complex Object Serialization
Preface: A bit of a digression I've found that when I don't update my blog, it's either because I'm extremely busy or because my efficiency is very low. I haven't updated the blog much recently, and the reason is the second one = =. How embarrassing. Today my efficiency was unusually high. I finished writing all the PassNote backend APIs in a single day. Django is great to use, but in actual projects there are still some features the framework can't implement that need to be solved. I quite like reinventing the wheel, but to keep efficiency up I still try to use existing tools as much as possible and cut down on unnecessary hassle. About PassNote I should have mentioned this on the blog before: this is a password management
目录11 个章节
Preface: A Bit of a Digression
I've found that when I don't update my blog, it's either because I'm extremely busy or because my efficiency is very low. I haven't updated the blog much recently, and the reason is the second one = =. How embarrassing. Today my efficiency was unusually high. I finished writing all the PassNote backend APIs in a single day. Django is great to use, but in actual projects there are still some features the framework can't implement that need to be solved. I quite like reinventing the wheel, but to keep efficiency up I still try to use existing tools as much as possible and cut down on unnecessary hassle.
About PassNote
I should have mentioned this on the blog before: this is a password manager for encrypting and storing various website accounts and passwords, and it can also generate high-strength passwords. Project homepage: https://deali-axy.github.io/PassNote/ Check it out. But this is only a desktop app and doesn't have cloud backup, so I've always wanted to find time to develop a cross-platform version. I've been putting it off, and only started writing it today.
Django Session Handling
Simply put, a session means taking the cookie and storing it on the server side, then the client uses the ID returned by the server as the session identifier.
The session framework lets you store and retrieve data about visitors. This information is stored on the server (in the database by default). Cookies are used to send and retrieve a value containing the session ID; cookies are not used to pass the data itself.
Using Sessions in Django
Enabling Sessions
Edit settings.py.
Add the following to MIDDLEWARE_CLASSES:
'django.contrib.sessions.middleware.SessionMiddleware',
Add the following to INSTALLED_APPS:
'django.contrib.sessions',
Using Sessions in Views
# 创建或修改 session:
request.session[key] = value
# 获取 session:
request.session.get(key,default=None)
# 删除 session
del request.session[key] # 不存在时报错
For more session usage, see the official docs: https://docs.djangoproject.com/en/2.0/topics/http/sessions/
On Serializing Complex Objects
There are already several solutions for serializing Django data:
django.core.serializers
Django's built-in serializer can serialize Django model querysets but cannot directly serialize a single Django model instance. If your model contains mixed data, this serializer also cannot be used (if you want to use the serialized data directly). Besides that, if you want to return the serialized data directly to the user, it clearly contains a lot of sensitive information as well as information that is useless to the user.
QuerySet.values()
Same as above, QuerySet.values() also won't work if your model has a DateTimeField or other special Fields, as well as extra data.
django-rest-framework serializers
django-rest-framework is a powerful framework that can help you quickly build REST APIs. It has a complete serializer, but before using it you need to spend some time getting started and learning the cbv development style. For projects with time constraints, this is clearly not the best solution.
Simply put, the several ready-made solutions in Django are either not powerful enough or have a high learning cost. Just as I was about to reinvent the wheel myself, I found a convenient solution, so to save time I immediately abandoned my plan of reinventing the wheel.
Project address: https://github.com/bluedazzle/django-simple-serializer Check it out.
But when actually using it there was another problem: when serializing a QuerySet, if it contains an AutoField it throws an error: 'AutoField' object has no attribute 'rel'
That's a bit of a trap. I finally found a useful tool so I wouldn't have to reinvent the wheel, only to suddenly discover this tool has a problem—and I have to fill in the hole for it??
Well, no choice, I had to step in. Since the code has no comments, and I didn't have that much time to figure out exactly where the problem was, I just fixed whatever was throwing errors. I also just filed an issue for the author on GitHub.
I modified the data_inspect function in the Serializer file. The code is as follows; I added a check for the rel attribute.
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
I tested it and it works normally, so I'll leave it like this for now, even though it feels a bit like "hack programming", hhh
End
That's all for these project notes. The new version of PassNote, like before, will be fully open-sourced after development is complete. This time I'm planning to make it cross-platform across mobile, desktop, and mini programs. Friends who are interested, feel free to follow along~
As is international custom, here's a screenshot.

_EOF_
Django Project Notes: Session Handling and Complex Object Serialization
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
Django过时了吗?从ASGI到AI时代的思考
Django过时?技术趋势变了而已,异步支持短板在AI时代更明显。生态工程化再稳,也挡不住轻量框架和ASGI的冲击。独立开发者该考虑新选择了?
2025-09-12 · Django · 约 1 分钟
Django的单元测试和集成测试
测试,在以前确实是经常被忽略的话题,特别是对于 Python Web 这种快速开发框架
2024-03-06 · Django · 约 1 分钟
Django数据库性能优化之使用Python集合操作
前言 最近有个新需求: 人员基础信息(记作人员A),10w 某种类型的人员信息(记作人员B),1000 要求在后台上(Django Admin)分别展示:已录入A的人员B列表、未录入的人员B列表 团队的DBA提议使用视图可以解决这个问题(不愧是搞数据库的) PS:起先我觉得Django的Model是直接管理数据库表的,使用Model来映射数据库模型怕是有一定的麻烦,不过查了一下资料发现并不会~ 只
2022-08-26 · Django · 约 1 分钟
告别单调,Django后台主页改造
前言 之前我做了个Django的项目,为了让管理后台更加美观,我对Django(应该说是SimpleUI的)默认的Admin后台主页进行改造,具体可以看这篇文章:项目完成 - 基于Django3.x版本 - 开发部署小结 之前的两篇关于Django3.x开发部署小结的文章介绍的都是数据库、接口、性能方面的,看到有朋友留言对后台主页的改造表示有兴趣,所以就写一篇来介绍一下~ 分析 改造基于我定制的
2022-06-28 · Django · 约 1 分钟
讨论
共 0 条加载评论中…