如何重写 Django 中的 model.Manager.create() 方法?

2024-05-22

我有很多Hardware模型有一个HardwareType具有各种特征。就像这样:

# models.py
from django.db import models

class HardwareType(model.Models):
    name = models.CharField(max_length=32, unique=True)

    # some characteristics of this particular piece of hardware
    weight = models.DecimalField(max_digits=12, decimal_places=3)
    # and more [...]        

class Hardware(models.Model):

    type = models.ForeignKey(HardwareType)

    # some attributes
    is_installed = models.BooleanField()
    location_installed = models.TextField()
    # and more [...]

如果我想添加一个新的Hardware对象,我首先必须检索HardwareType每次,这不是很干:

tmp_hd_type = HardwareType.objects.get(name='NG35001')
new_hd = Hardware.objects.create(type=tmp_hd_type, is_installed=True, ...)

因此,我尝试重写HardwareManager.create()创建新类型时自动导入类型的方法Hardware像这样:

# models.py
from django.db import models

class HardwareType(model.Models):
    name = models.CharField(max_length=32, unique=True)

    # some characteristics of this particular piece of hardware
    weight = models.DecimalField(max_digits=12, decimal_places=3)
    # and more [...] 

class HardwareManager(models.Manager):
    def create(self, *args, **kwargs):
        if 'type' in kwargs and kwargs['type'] is str:
            kwargs['type'] = HardwareType.objects.get(name=kwargs['type'])
        super(HardwareManager, self).create(*args, **kwargs)       

class Hardware(models.Model):
    objects = HardwareManager()

    type = models.ForeignKey(HardwareType)

    # some attributes
    is_installed = models.BooleanField()
    location_installed = models.TextField()
    # and more [...]

# so then I should be able to do:
new_hd = Hardware.objects.create(type='ND35001', is_installed=True, ...)

但我不断收到来自 ORM 的错误和非常奇怪的行为(我这里没有,但如果需要的话我可以发布它们)。我在 Django 文档和 SO 线程中进行了搜索,但大多数情况下我最终得到的解决方案是:

  • the Hardware.save()方法被重写(我应该得到HardwareType在那里?)或者,
  • 经理定义了一个新的create_something调用的方法self.create().

我也开始深入研究代码并发现Manager是某种特殊的QuerySet但我不知道如何从那里继续。我真的很想更换create方法到位,我似乎无法管理这个。是什么阻止我做我想做的事?


洞察来自Alasdair https://stackoverflow.com/users/113962/alasdair的答案对捕获字符串和 unicode 字符串有很大帮助,但实际上缺少的是return调用之前的声明super(HardwareManager, self).create(*args, **kwargs) in the HardwareManager.create() method.

昨天晚上我在测试中遇到的错误(编码不是一个好主意时感到疲倦:P)是ValueError: Cannot assign None: [...] does not allow null values.因为后续的使用new_hd我有create()d was None因为我的create()方法没有return。多么愚蠢的错误啊!

最终更正后的代码:

class HardwareManager(models.Manager):
    def create(self, *args, **kwargs):
        if 'type' in kwargs and isinstance(kwargs['type'], basestring):
            kwargs['type'] = HardwareType.objects.get(name=kwargs['type'])
        return super(HardwareManager, self).create(*args, **kwargs)   
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何重写 Django 中的 model.Manager.create() 方法? 的相关文章

随机推荐