2017-06-29 55 views
1

*****使用Django 1.11.x和Python 3.6 *****在Django模型使用save()产生类型错误

我想学习如何使用save()方法的工作一个Django模型(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和年龄。然后我定义了两个@property方法,每个方法返回不同类型的结果。 “get_unique_id”函数可以工作,但我无法获得存储在数据库中的结果。 “get_age”函数可能会或可能不会工作。我还没有能够制作它。

我的主要问题是如何正确使用save()函数与我的“计算领域”的方法来覆盖初始字段值(UNIQUE_ID年龄)(get_unique_idget_age) 。

我的主要问题是,当我加人(使用人的ModelForm在/管理员)时,它产生一个类型错误:“STR”对象不是在该行可调用self.unique_id = self.get_unique_id()“。我目前正在使用Admin界面进行测试。

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

我有一个关于* args和** kwargs的第二个问题(我对django的新手道歉)。离开他们在那里可以吗?我真的不确定我需要使用哪些参数,以及是否有必要在代码中包含* args和** kwargs。

注意:对于任何人谁昨天帮我这个应用程序,我真的很感谢你的帮助。我认为这与我以前的问题不同,尽管我使用了大部分相同的代码。

+0

不要这样做。将年龄设置为单独的字段没有意义,因为它会过时。当你需要时计算它。 –

+0

好的,谢谢。我可以忍受这一点。unique_id是更重要的一个。 –

回答

2

属性不可调用。当你访问self.get_unique_id时,Python会在后台调用底层方法@property,在这种情况下返回一个字符串。您不必再调用它,删除括号:

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成为属性。

+0

这工作!谢谢。 –

+0

@RonRaney你可能会考虑接受答案,如果它有帮助 –

+0

我低于15分,所以他们不喜欢我的意见:) –