Django源码解析|Migrations文件的生成

栏目: Python · 发布时间: 6年前

内容简介:这其实是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程序员杂谈

Django源码解析|Migrations文件的生成

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算机算法基础

计算机算法基础

沈孝钧 / 机械工业出版社 / 2013-11 / 45.00元

计算机算法是计算机科学的一个重要分支,也是一个难点。本书作者根据自己20多年在国内、国外的教学与科研实践,系统地总结了计算机算法的设计与分析方法,覆盖了大部分最主要的算法技术,包括:分治法、贪心法、动态规划、图的遍历技术、穷举搜索等,涉及一系列重要的算法问题,包括排序问题、选择问题、最小生成树问题、最短路径问题、网络流问题、二分图的匹配问题、字符串的匹配问题和几何算法问题等,还介绍了问题本身的计算......一起来看看 《计算机算法基础》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码