How to replace a Django model field with a property
2015-12-14 13:59
537 查看
If you use Django for your web apps, you will probably have come across a situation where you need to run some custom code on assigning a value to a model field. You’ve probably hacked around this by overriding the save() method or some other arcane hackery,
but this is not only unnecessary, but it’s more complicated than it should be.
You can use a Python
property to add a getter/setter to the field and run your custom code there. Even better, you don’t even have to change your database or run any migrations to do this.
Since you can’t just create a getter and a setter with the same name as the field (Django will be confused, as it will only see the method and not the shadowed field), you can rename the field. My preferred solution is to prepend the field with an underscore,
but still keep the same field column name, to keep everything working as it used to.
So if, for example, you have a date field that you need to run some additional logic on, you can do the following:
If the original model looks like this:
You can add a property like so:
This way, the entire codebase can stay as-is, without needing to be updated at all. You can even remove the original field and replace it with other functionality, faking it entirely, or remove the properties in the future when you don’t need the custom
behavior. It’s perfectly backwards- and forwards-compatible, and very easy to do.
but this is not only unnecessary, but it’s more complicated than it should be.
You can use a Python
property to add a getter/setter to the field and run your custom code there. Even better, you don’t even have to change your database or run any migrations to do this.
Since you can’t just create a getter and a setter with the same name as the field (Django will be confused, as it will only see the method and not the shadowed field), you can rename the field. My preferred solution is to prepend the field with an underscore,
but still keep the same field column name, to keep everything working as it used to.
So if, for example, you have a date field that you need to run some additional logic on, you can do the following:
If the original model looks like this:
class MyClass(models.Model): my_date = models.DateField()
You can add a property like so:
class MyClass(models.Model): _my_date = models.DateField(db_column="my_date") @property def my_date(self): return self._my_date @my_date.setter def my_date(self, value): if value > datetime.date.today(): logger.warning("The date chosen was in the future.") self._my_date = value
This way, the entire codebase can stay as-is, without needing to be updated at all. You can even remove the original field and replace it with other functionality, faking it entirely, or remove the properties in the future when you don’t need the custom
behavior. It’s perfectly backwards- and forwards-compatible, and very easy to do.
Subscribe to my mailing list
Did you like what you just read and want to be notified when I post more? Subscribe to my mailing list to get updates on my posts and other random goodies.相关文章推荐
- Linux下Rsync+Inotify-tools实现数据实时同步-(转载)
- linux之间利用scp传输文件
- Linux下ffmpeg的完整安装
- linux安装svn服务器(yum方式)
- ceph存储 Linux 编译安装Boost
- linux开启防火墙挂载nfs
- CentOS 6.2 LNMP 环境搭建优化笔记
- OpenResty 反向代理的用法与技巧
- Centos下编译安装mysql
- [笔记] 大型网站技术架构——核心原理与案例分析 [十]
- linux rsync介绍
- Working with Apache Derby
- Windows软件在Linux上的等价/替代/模仿软件列表 (抄一个)
- 解决Xcode 9.2系统真机测试时出现 could not find developer disk image问题
- docker basic guide
- 让linux的history命令显示操作时间
- linux编译boost
- [笔记] 大型网站技术架构——核心原理与案例分析 [九]
- adb shell 删除文件夹常用指令
- 使用BASH脚本查看VSFTP的日志登录情况