我想在我的模特中为BTC和LTC硬币制作钱包。但是,由于大多数代码与coin_name
和tx_fees
相同。
所以,我想创建一个这样的辅助类:
电子钱包课(摘录)
class Wallet(models.Model):
name = models.CharField(max_length=80, editable=False)
trading_amt = models.FloatField(default=0, validators=[MinValueValidator(0.0), ])
wallet_amt = models.FloatField(default=0, validators=[MinValueValidator(0.0), ])
wallet_address = models.CharField(default='', blank=True, max_length=100)
coin_name = '' <-- will it serve the purpose ?
tx_fee = 0 <-- and this ?
def __init__(self, coin_name, tx_fee):
self.coin_name = coin_name
self.tx_fee = tx_fee
@transaction.atomic
def moveToTrading(self, amount):
if amount > self.wallet_amt:
return "Insufficient balance"
else:
self.trading_amt += amount
self.wallet_amt -= amount
return True
@transaction.atomic
def withdraw(self, amount, withdrawal_wallet_addr):
if amount > self.wallet_amt:
return "Insufficient balance"
else:
# First check if withdrawal address entered by user is
# correct, using wallet daemon , if not return error
if check_wallet(withdrawal_wallet_addr, "btc"):
# initiate checkout
return initiate_checkout(withdrawal_wallet_addr, self.coin_name, self.tx_fee)
else:
return "Incorrect Wallet address"
def save(self, *args, **kwargs):
self.name = gen_random_string('btc_wallet')
super(Wallet, self).save(*args, **kwargs)
def deposit(self, amount):
self.wallet_amt += amount
def __unicode__(self):
return self.name
def __str__(self):
return self.name
仅在创建钱包地址coin_name
时使用name
:_btc_wallet_&lt; 64 char随机字符串&gt; _
并且tx_fee
作为常量存储在每个硬币的 helpers.py 中
因此,将它们保存在数据库中是没有意义的。
我在OOP编程中是一个小菜鸟(我知道它们是什么,但是编码不多)所以很困惑这是什么才是正确的用法:
class BtcWallet(Wallet):
def __init__(self, coin_name, tx_fee):
self.tx_fee = BTC_FEES
self.coin_name = "BTC"
super(BtcWallet, self).__init__(coin_name, tx_fee)
class BtcWallet(Wallet):
def __init__(self, coin_name, tx_fee):
self.tx_fee = BTC_FEES
self.coin_name = "BTC"
即。我是否需要初始化超级初始化程序?
如果使用super,那么应该如何使用,例如:
super(BtcWallet, self).__init__(coin_name, tx_fee)
或
super(Wallet, self).__init__(coin_name, tx_fee)
由于coin_name
和tx_fees
未保存在数据库中,所以何时会失败?就像什么时候不接受这些价值。
也许,它不应该失败因为无论在哪里使用它都会有一个对象?
BtcWallet
是 userprofile 模型的外键元素。如果我像这样使用它会失败
request.user.profile.BTC_wallet.withdraw()
(我可以在其中一个视图中使用它)
UserProfile模型(摘录)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
joining_date = models.DateTimeField(default=timezone.now)
BTC_wallet = models.OneToOneField(BtcWallet, on_delete=models.SET_NULL, related_name='profile', null=True,
blank=True)
更改为新表单后(之前我的代码中没有任何钱包类,而钱包类是BtcWallet类),并将迁移结果转换为:
jame@vostro:~/mywebsite# python manage.py makemigrations account
You are trying to add a non-nullable field 'wallet_ptr' to btcwallet without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option:
答案 0 :(得分:0)
__ pycache __ ,#django的其中一个人帮助我解决了这个问题。
对于抽象类,钱包类必须是抽象类 Meta Class options和here。
抽象类不会被制作成表格模型,并且可以作为辅助类使用。
class Wallet(models.Model):
name = models.CharField(max_length=80, editable=False)
trading_amt = models.FloatField(default=0, validators=[MinValueValidator(0.0), ])
wallet_amt = models.FloatField(default=0, validators=[MinValueValidator(0.0), ])
wallet_address = models.CharField(default='', blank=True, max_length=100)
coin_name = ''
tx_fee = 0
@transaction.atomic
def moveToTrading(self, amount):
if amount > self.wallet_amt:
return "Insufficient balance"
else:
self.trading_amt += amount
self.wallet_amt -= amount
return True
@transaction.atomic
def withdraw(self, amount, withdrawal_wallet_addr):
if amount > self.wallet_amt:
return "Insufficient balance"
else:
# First check if withdrawal address entered by user is
# correct, using wallet daemon , if not return error
if check_wallet(withdrawal_wallet_addr, self.coin_name):
# initiate checkout
return initiate_checkout(withdrawal_wallet_addr, self.coin_name, self.tx_fee)
else:
return "Incorrect Wallet address"
def save(self, *args, **kwargs):
self.name = gen_random_string(self.coin_name.lower()+'_wallet')
super(Wallet, self).save(*args, **kwargs)
def deposit(self, amount):
self.wallet_amt += amount
def __unicode__(self):
return self.name
def __str__(self):
return self.name
class Meta: <-------Added this
abstract = True
**和BtcWallet课程:**
class BtcWallet(Wallet):
def __init__(self, *args, **kwargs):
self.coin_name = "BTC"
self.tx_fee = COINS[self.coin_name]['tx_fee']
super(BtcWallet, self).__init__(*args, **kwargs)
super
,因为我们要重写 init 方法,并且需要为每个被覆盖的函数调用它。
Python 2.x --> super(subclassName, self).__init__(*args, **kwargs)
Python 3.x --> super().__init__(*args, **kwargs)
由Raymond Hettinger在超级上查看this nice article,非常有帮助且明确。