以下是我正在创建的自定义字段:
class TransactionStateField(with_metaclass(models.SubfieldBase, models.CharField)):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 255
super(TransactionStateField, self).__init__(*args, **kwargs)
def to_python(self, value):
if value:
print value.__class__, 11111111111
kls = import_by_path(value)
return kls()
return None
def get_prep_value(self, value):
if value:
return fullname(value)
return None
这是模型:
class AbstractTransaction(models.Model):
processed_at = models.DateTimeField(null=True, blank=True)
cancelled_at = models.DateTimeField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
amount = models.DecimalField(max_digits=10, decimal_places=2)
class Meta:
abstract = True
def process(self):
raise NotImplemented()
class Transaction(AbstractTransaction):
CURRENCIES = (('NZD', 'New Zealand Dollars'), ('EUR', 'Euro'))
currency = models.CharField(choices=CURRENCIES, max_length=25)
user_goid = models.CharField(null=True, blank=True, max_length=255)
order_goid = models.CharField(null=True, blank=True, max_length=255)
billingtoken = models.ForeignKey('BillingToken', null=True, blank=True)
state = TransactionStateField(default='project.apps.transactions.states.NewTransaction')
def process(self):
self.state.process(self)
def __unicode__(self):
return "{} ${}".format(self.currency, self.amount)
这是管理员:
class SubTransactionInline(admin.StackedInline):
model = SubTransaction
extra = 0
class TransactionAdmin(admin.ModelAdmin):
inlines = [SubTransactionInline]
admin.site.register(Transaction, TransactionAdmin)
当我在admin中创建事务记录(内联中没有子事务)时,使用不同的值类型调用to_python
方法3次
<type 'unicode'> 11111111111
<type 'unicode'> 11111111111
<class 'project.apps.transactions.states.NewTransaction'> 11111111111
你看到最后一个是另一种造成麻烦的类型。
但是如果我在python manage.py shell
创建记录,它只会被调用一次:
>>> t = Transaction.objects.create(amount=11111, currency='NZD')
<type 'unicode'> 11111111111