Mô hình Discount
của tôi mô tả các trường phổ biến cho tất cả các loại giảm giá trong hệ thống. Tôi có một số mô hình proxy mô tả thuật toán cụ thể cho tổng số. Lớp cơ sở Discount
có trường thành viên có tên là type
, là một chuỗi nhận dạng loại của nó và lớp liên quan của nó.Mô hình đa hình django với kế thừa proxy
class Discount(models.Model):
TYPE_CHOICES = (
('V', 'Value'),
('P', 'Percentage'),
)
name = models.CharField(max_length=32)
code = models.CharField(max_length=32)
quantity = models.PositiveIntegerField()
value = models.DecimalField(max_digits=4, decimal_places=2)
type = models.CharField(max_length=1, choices=TYPE_CHOICES)
def __unicode__(self):
return self.name
def __init__(self, *args, **kwargs):
if self.type:
self.__class__ = getattr(sys.modules[__name__], self.type + 'Discount')
super(Discount, self).__init__(*args, **kwargs)
class ValueDiscount(Discount):
class Meta:
proxy = True
def total(self, total):
return total - self.value
Nhưng tôi vẫn nhận ngoại lệ của AttributeError nói rằng bản thân không có loại. Làm thế nào để sửa lỗi này hoặc là có một cách khác để đạt được điều này?
Cảm ơn bạn. Còn một câu hỏi nữa, tại sao tôi cần gọi super __init__ trước khi truy cập các thuộc tính của đối tượng? Tôi nghĩ rằng đó là một con trăn mà làm cho tất cả các thành viên tuyên bố trong đối tượng có thể truy cập trong constructor, không phải siêu lớp (models.Model từ Django). Làm thế nào mà? – aambrozkiewicz
Điều này là do django.db.models.Model có '__metaclass__ = ModelBase'. Điều này có nghĩa là django sử dụng 'ModelBase' để tạo lớp Model của bạn thay vì' type' thông thường. Tôi khuyên bạn nên đọc: http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python - và một khi bạn đã thành thạo metaclasses, hãy xem mã nguồn django. –