dr *_*bob 79 python django django-models django-1.2
我有一个模型,我想包含一个主题名称和他们的首字母.(这些数据有些匿名,并通过首字母进行跟踪.)
现在,我写道
class Subject(models.Model):
name = models.CharField("Name", max_length=30)
def subject_initials(self):
return ''.join(map(lambda x: '' if len(x)==0 else x[0],
self.name.split(' ')))
# Next line is what I want to do (or something equivalent), but doesn't work with
# NameError: name 'self' is not defined
subject_init = models.CharField("Subject Initials", max_length=5, default=self.subject_initials)
Run Code Online (Sandbox Code Playgroud)
如最后一行所示,我希望能够将首字母实际存储在数据库中作为字段(独立于名称),但是使用基于名称字段的默认值进行初始化.但是,我有问题,因为django模型似乎没有"自我".
如果我将行更改为subject_init = models.CharField("Subject initials", max_length=2, default=subject_initials)
,我可以执行syncdb,但无法创建新主题.
这在django中是否可行,具有可调用函数根据另一个字段的值给出某个字段的默认值?
(好奇的是,我想分开我的商店首字母的原因是极少数情况下奇怪的姓氏可能与我跟踪的名字不同.例如,有人认为主题1命名为"John O'Mallory"的首字母是"JM"而不是"JO",并希望修改为管理员.)
Elf*_*erg 77
模特肯定有一个"自我"!只是你试图将模型类的属性定义为依赖于模型实例; 这是不可能的,因为在定义类及其属性之前,实例不存在(也不能存在).
要获得所需的效果,请覆盖模型类的save()方法.根据需要对实例进行任何更改,然后调用超类的方法进行实际保存.这是一个简单的例子.
def save(self, *args, **kwargs):
if not self.subject_init:
self.subject_init = self.subject_initials()
super(Subject, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
这在文档中的Overriding Model Methods中有所介绍.
Gab*_*aru 15
我不知道是否有这样做的更好的办法,但你可以使用一个信号处理器对于该pre_save
信号:
from django.db.models.signals import pre_save
def default_subject(sender, instance, using):
if not instance.subject_init:
instance.subject_init = instance.subject_initials()
pre_save.connect(default_subject, sender=Subject)
Run Code Online (Sandbox Code Playgroud)
使用Django的信号,这可以很早就完成,通过接收的post_init
信号从模型。
from django.db import models
import django.dispatch
class LoremIpsum(models.Model):
name = models.CharField(
"Name",
max_length=30,
)
subject_initials = models.CharField(
"Subject Initials",
max_length=5,
)
@django.dispatch.receiver(models.signals.post_init, sender=LoremIpsum)
def set_default_loremipsum_initials(sender, instance, *args, **kwargs):
"""
Set the default value for `subject_initials` on the `instance`.
:param sender: The `LoremIpsum` class that sent the signal.
:param instance: The `LoremIpsum` instance that is being
initialised.
:return: None.
"""
if not instance.subject_initials:
instance.subject_initials = "".join(map(
(lambda x: x[0] if x else ""),
instance.name.split(" ")))
Run Code Online (Sandbox Code Playgroud)
该post_init
信号由类一旦完成初始化的实例发送。这样,实例name
在测试是否设置了其非空字段之前会获取一个值。
归档时间: |
|
查看次数: |
33039 次 |
最近记录: |