简体   繁体   English

弃用 Django 模型中的字段

[英]Deprecating fields in django model

I'm normalizing a database associated with a Django project and will be moving fields to different tables.我正在规范与 Django 项目关联的数据库,并将字段移动到不同的表。 As part of the implementation process, I'd like to throw a deprecation warning to my colleagues if they attempt to use the old attributes after adding the new tables before I actually remove the columns.作为实施过程的一部分,如果我的同事在我实际删除列之前添加新表后尝试使用旧属性,我想向他们发出弃用警告。

class Asset(Model):
    model = models.CharField(max_length=64, blank=True, null=True)
    part_number = models.CharField(max_length=32, blank=True, null=True) # this will be a redundant column to be deprecated
    company = models.ForeignKey('Company', models.CASCADE, blank=True, null=True) # this will be a redundant column to be deprecated
    # other database fields as attributes and class methods

My understanding is that I would need to add something along the lines of warnings.warn('<field name> is deprecated', DeprecationWarning) somewhere in the class, but where would I add it?我的理解是我需要在类中的某个地方添加一些类似于warnings.warn('<field name> is deprecated', DeprecationWarning)的内容,但是我应该在哪里添加它?

You can use django_deprication.DeprecatedField您可以使用django_deprication.DeprecatedField

pip install django-deprecation

then use like this然后像这样使用

class Album(models.Model):
    name = DeprecatedField('title')

https://github.com/openbox/django-deprecation https://github.com/openbox/django-deprecation

Perhaps you could use Django's system check framework (introduced in Django 1.7).也许您可以使用 Django 的系统检查框架(在 Django 1.7 中引入)。

Some interesting examples, using the system-check-framework for deprecation of custom fields, are provided in the migrations docs . 迁移文档中提供了一些有趣的示例,使用系统检查框架来弃用自定义字段。

It seems you can also use this approach to mark standard fields on your model.似乎您也可以使用这种方法来标记模型上的标准字段。 Applied to the example from the original post, the following works for me (tested in Django 3.1.6).应用于原始帖子中的示例,以下内容对我有用(在 Django 3.1.6 中测试)。

class Asset(Model):
    ...
    company = models.ForeignKey('Company', models.CASCADE, blank=True, null=True)  
    company.system_check_deprecated_details = dict(
        msg='The Asset.company field has been deprecated.',
        hint='Use OtherModel.other_field instead.',
        id='fields.W900',  # pick a unique ID for your field.
    )
    ...

See the system check API reference for more detailed information, eg about the "unique ID".有关更多详细信息,例如有关“唯一 ID”的信息,请参阅系统检查 API 参考

The following warning will then show, whenever you call runserver , migrate , or other commands, as mentioned in the docs :每当您调用runservermigrate或其他命令时,都会显示以下警告,如文档中所述

System check identified some issues:

WARNINGS:
myapp.Asset.company: (fields.W900) The Asset.company field has been deprecated.
    HINT: Use OtherModel.other_field instead.

Also nice to know (from the docs):也很高兴知道(来自文档):

... For performance reasons, checks are not run as part of the WSGI stack that is used in deployment. ... 出于性能原因,检查不作为部署中使用的 WSGI 堆栈的一部分运行。 ... ...

I do something similar to this - turn the field into a property and handle the warning there.我做了类似的事情 - 将字段转换为属性并在那里处理警告。 Note that this will still break any queries you make that filter on the field - just helps with accessing the attribute from instances.请注意,这仍然会破坏您对该字段进行的任何查询 - 仅有助于从实例访问属性。

class NewAsset(Model):
    model = models.CharField(max_length=64, blank=True, null=True)

class Asset(Model):
    @property
    def model(self):
        log.warning('Stop using this')
        return NewAsset.model

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM