2009-09-01 62 views
6

Tôi muốn sử dụng các thuộc tính từ lớp Meta của mô hình kế thừa để định cấu hình trường được xác định trong mô hình trừu tượng cao hơn cây thừa kế:Không thể sử dụng lớp Meta của mô hình Django kế thừa để định cấu hình trường được xác định trong mô hình trừu tượng được thừa kế

class NamedModel(models.Model): 
    class Meta: 
     abstract = True 
     verbose_name = 'object' 

    name = models.CharField("Name", 
     max_length=200, 
     db_index=True, 
     help_text="A meaningful name for this %s." % Meta.verbose_name) 
     # see what I'm trying to do here? 
    ) 
    ... 

class OwnedModel(NamedModel): 
    class Meta(NamedModel.Meta): 
     verbose_name = 'owned object' 

Tôi muốn văn bản trợ giúp về trường tên của biểu mẫu OwnedModel để nói 'Tên có ý nghĩa cho đối tượng sở hữu này'. Nhưng nó không: từ 'sở hữu' là mất tích, mà sẽ gợi ý rằng verbose_name từ NamedModel.Meta được sử dụng khi mô hình được thiết lập, không phải là OwnedModel.Meta.

Đây không phải là điều tôi mong đợi từ quan điểm thừa kế: có cách nào đó để tạo trường được Meta.verbose_name đề cập đến giá trị trên lớp mô hình không trừu tượng, không phải là lớp trừu tượng mà trường được xác định?

Hoặc tôi có bị trục trặc không?

(Điều này có vẻ giống như một ví dụ nhỏ, và nó là: nhưng nó chỉ là để minh họa cho quan điểm của một cái gì đó quan trọng hơn và phức tạp Tôi cố gắng để làm)

Nhiều cảm ơn trước.

Trả lời

1

Tôi nghĩ điều này xảy ra vì Meta.verbose_name được sử dụng và NamedModel.name được tạo khi lớp NamedModel được phân tích cú pháp. Vì vậy, sau này, khi lớp OwnedModel được phân tích cú pháp, không có cơ hội thay đổi bất cứ điều gì.

Có thể bạn có thể đặt thuộc tính help_text trên OwnedModel.name sau này, nhưng điều này cũng có thể thay đổi tên NamedModel.name.

Trong các trường hợp tương tự, tôi đã đặt các phần biến trong thuộc tính lớp của mô hình (không phải Meta) và sau đó sử dụng các phương thức/thuộc tính thời gian chạy để tạo các văn bản tôi cần.

+0

Vâng, tôi nghĩ đó là nó. Đã theo dõi luồng tôi rõ ràng hơn trên vòng đời: các trường được đánh giá khi lớp được phân tích cú pháp, vì vậy thừa kế không được xem xét. Và tôi đã thử các thuộc tính lớp ngoài meta ... cùng một vấn đề. Tôi rất vui khi ghi đè các lớp trường và tôi có thể sử dụng (+ những gì bạn đề xuất) để có được hiệu quả mong muốn. –

1

Thực ra tôi đã làm như sau. Mô hình cơ sở được đưa ra một phương thức lớp dynamic_field_definition(), có thể được sử dụng để vá các trường, với đối số cls là lớp chính xác (kế thừa). Điều đó có nghĩa rằng các thuộc tính Meta của cl đó là của đứa trẻ chính xác, không phải là cơ sở gốc.

Tôi sau đó kết nối phương thức đó để được gọi trên tín hiệu class_prepared, để bạn biết mọi thứ đã sẵn sàng.

class NamedModel(models.Model): 
    ... 
    @classmethod 
    def dynamic_field_definition(cls): 
     pass 

def dynamic_field_definition(sender, **kwargs): 
    if issubclass(sender, NamedModel): 
     sender.dynamic_field_definition() 
class_prepared.connect(dynamic_field_definition) 

Sau đó, các thuộc tính lĩnh vực mà thay đổi theo mô hình lớp học chỉ đơn giản là cấu hình lại bằng phương pháp lớp học (hoặc nhiều khả năng phương pháp như ghi đè trong các lớp thừa kế).

Đó là một cách hơi khó để mang lại một chút cuối cùng của mô hình OO-Ness cho Django, nhưng nó hoạt động tốt cho mục đích của tôi.

2

Tại sao bạn không cố gắng tạo lớp học.

class BaseNamedModelMeta: 
    abstract = True 
    verbose_name = "your text" 

Và sau đó kế thừa và ghi đè lên bất cứ điều gì bạn muốn như thế này:

class OwnedModel(NamedModel): 
    class Meta(BaseNamedModelMeta): 
     verbose_name = 'owned object' 
Các vấn đề liên quan