内容简介:这其实是Django源码解析视频中的一个细节。当我们创建好一个Model之后,需要执行比如Mode定义如下:
背景
这其实是Django源码解析视频中的一个细节。
当我们创建好一个Model之后,需要执行 makemigrations
操作,生成对应的Migrations文件。那么问题来了,Django是如何把Model生成对应的Migrations文件的呢?
比如Mode定义如下:
from django.db import models class Post(models.Model): title = models.CharField(max_length=100) created_time = models.DateTimeField(auto_now_add=True)
生成的Migrations如下:
from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='Post', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=100)), ('created_time', models.DateTimeField(auto_now_add=True)), ], ), ]
其实我们关心的是operations里面的内容。
需要注意的是,这个代码也是文本,是由Django生成的。
代码实现
视频里虽然讲解了,不过最好大家还是能够自己实现一个简单的逻辑,这样才能掌握更多技巧和库的用法。话不多说,我们直接上代码,实现一个小的Demo。
import inspect class CreateModel: def __init__(self, name, age=20): self.name = name self.age = age def deconstruct(self): kwargs = { 'name': self.name, 'age': self.age, } return ( self.__class__.__qualname__, [self.name], kwargs ) def get_func_args(func): # django/utils/inspect.py sig = inspect.signature(func) return [ arg_name for arg_name, param in sig.parameters.items() if param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD ] def rewrite(foo): name, args, kwargs = foo.deconstruct() operation_args = get_func_args(foo.__init__) buf = [] buf.append(f'{name}(') for i, arg in enumerate(args): arg_value = arg arg_name = operation_args[i] buf.append(f'"{arg_value}",') i = len(args) for arg_name in operation_args[i:]: if arg_name in kwargs: arg_value = kwargs[arg_name] buf.append(f'{arg_name}={arg_value},') buf.append(')') print('\n'.join(buf)) if __name__ == '__main__': # 把下面的定义转写到文件中 foo = CreateModel( 'the5fire', age=30 ) rewrite(foo)
上面代码的核心是通过inspect对拿到的类实例(也就是: foo
)进行解析,整体逻辑不难理解。
很多人觉得这个定义已然存在了,为什么还要通过代码来写一遍。关键问题在于, 我们需要站在机器的视角来看问题 。机器拿到的只是一个对象,它需要做的是把对象转换为文本。
- from the5fire.com
----EOF-----
微信公众号:Python程序员杂谈
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Vue源码简析之视图生成(上)
- babel源码分析之一:AST生成
- symfony源码分析之容器的生成与使用
- Golang SQL生成库 Squirrel 教程及源码阅读
- mybatis源码学习:从SqlSessionFactory到代理对象的生成
- 木兰语言 0.0.17:着手由 Python 语法树生成木兰源码
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。