在Django模型中使用save()会产生TypeError

时间:2017-06-29 17:51:46

标签: python django django-models save custom-fields

*****使用Django 1.11.x和Python 3.6 *****

我试图学习如何在Django模型中使用save()方法(models.py)。这里有两个字段,我想成为自定义,'计算'字段(unique_id和年龄)。

首先我启动字段变量,然后根据现有字段定义方法/属性,然后尝试将方法结果保存到我创建的字段中。

from django.db import models
from dateutil.relativedelta import relativedelta
from datetime import datetime

class Person(models.Model):
    unique_id = models.CharField(max_length=6, primary_key=True)
    age = models.IntegerField()
    last_name = models.CharField(max_length=25)
    birth_date = models.DateField()
    city_of_birth = models.CharField(max_length=25)

    @property
    def get_unique_id(self):
        a = self.last_name[:2].upper()     #First 2 letters of last name
        b = self.birth_date.strftime('%d')     #Day of the month as string
        c = self.city_of_birth[:2].upper()     #First 2 letters of city
        return a + b + c 

    @property
    def get_age(self):
        return relativedelta(self.birth_date.days, datetime.date.now()).years

    def save(self, *args, **kwarg):
        self.unique_id = self.get_unique_id()
        self.age = self.get_age()
        super(Person, self).save(*args, **kwarg)

    def __str__(self):
        return self.unique_id

首先,我创建了5个字段。其中2个是占位符:unique_id和age。然后我定义了两个@property方法,每个方法返回一个不同类型的结果。 " get_unique_id"功能有效,但我无法将结果存储在数据库中。 " get_age"功能可能有效也可能无效。我还没有能够生产它。

我的主要问题是如何正确使用save()函数覆盖初始字段值( unique_id age ) '计算字段'方法( get_unique_id get_age )。

我的主要问题是当我添加一个Person(在/ Admin中使用Person ModelForm)时,会产生一个 TypeError: ' str& #39;对象不可调用在第" self.unique_id = self.get_unique_id()"。我目前正在使用Admin界面进行测试。

最后,我需要学习如何不在表单中显示这两个字段,因为它们将根据其他字段计算。我想我可能已经找到了有关Meta的文档可能有所帮助。另外,我希望unique_id字段是主键,因此我将此选项添加到初始字段。

对于* args和** kwargs,我有一个次要问题(我对Django不熟悉)。可以把它们留在那里吗?我真的不确定我需要使用哪些参数,如果有的话,以及是否需要在代码中包含* args和** kwargs。

注意 :对于昨天使用此应用程序帮助过我的人,我非常感谢您的帮助。我认为这与我之前的问题有所不同,尽管我使用了大量相同的代码。

1 个答案:

答案 0 :(得分:4)

属性不可调用。当您访问self.get_unique_id时,Python会在幕后调用由@property修饰的基础方法,在这种情况下会返回一个字符串。您不需要再次调用它,删除parens:

def save(self, *args, **kwarg):
    self.unique_id = self.get_unique_id
    self.age = self.get_age
    super(Person, self).save(*args, **kwarg)

OTOH,请参阅@ DanielRoseman的评论,您不需要在数据库中存储年龄。只需在需要时计算它。您可以将get_age重命名为age并删除age字段,以便age成为属性。