在Django模型中添加代码和方法会破坏它

时间:2018-10-31 10:19:06

标签: python django python-3.x model

我有一个与此相似的Django模型:

class Person(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.TextField(unique=False)

我想在models.py文件之外向一个人添加代码。所以我尝试导入它,从中继承并添加代码:例如:

class MyPerson(db.Person):
    def __init__(self, person_name):
        super(MyPerson, self).__init__(name=person_name)

    def print_person_info(self):
        print(self.name)

我收到与此类似的错误:

RuntimeError:模型类db.persons.models.Person没有声明显式的app_label,并且不在INSTALLED_APPS的应用程序中。

尽管当然在我的settings.py文件中,我确实将我的persons应用添加到INSTALLED_APPS

我想我可以直接在models.py内添加代码,但这似乎很不方便,因为我想在其中添加更多代码,并且要针对多个模型。

有什么想法吗?

从模型继承通常可以,建议吗?

1 个答案:

答案 0 :(得分:4)

  

我想在models.py文件之外向一个人添加代码。因此,我尝试将其导入,继承并添加代码。

继承 Django模型。 Django将此视为 extra 模型(继承)。因此,它必须在数据库端构造一个额外的表,该表具有对“父对象”的引用,在某些情况下,您的额外字段会指定这些表。但是由于您可能定义了此类 outside models.py,所以找不到app_label,因此,许多任务无法执行。

  

从模型继承通常可以,建议吗?

否,仅来自抽象模型,但这是另一个用例,而不是这里的用例。可以从非抽象模型继承,但是我仍然不建议这样做,因为这在数据库级别会造成很多额外的麻烦。

通常,如果您想添加行为,则可以直接在模型类上进行 操作,例如:

class Person(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.TextField(unique=False)

    def print_person_info(self):
        print(self.name)

或者如果行为与您已定义的行为不同,则可以使用proxy model [Django-doc]来使两个模型类在同一个数据库表上工作,每个模型类的行为均相同,例如:

class MyPerson(db.Person):

    class Meta:
        proxy = True

    def print_person_info(self):
        print(self.name)

但是代理也可能带来很多额外的“复杂性”,因此建议仅将其用作“最后的手段”。

真的建议不要 修补__init__函数,并且绝对不要更改参数(如果这样做,请使用*args和{{1} }传递所有参数),例如:

**kwargs

在Django中,许多类都假设它们可以通过调用构造函数不带参数或通过将字段名称与值一起传递来创建模型实例。通过更改此行为,将需要重写许多类,以便您可以在表单,基于类的视图等中使用模型。