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文件的生成

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

查看所有标签

猜你喜欢:

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

Web Development Recipes

Web Development Recipes

Brian P. Hogan、Chris Warren、Mike Weber、Chris Johnson、Aaron Godin / Pragmatic Bookshelf / 2012-1-22 / USD 35.00

You'll see a full spectrum of cutting-edge web development techniques, from UI and eye candy recipes to solutions for data analysis, testing, and web hosting. Make buttons and content stand out with s......一起来看看 《Web Development Recipes》 这本书的介绍吧!

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

在线压缩/解压 JS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具