2010-07-15 27 views
45

Đây là câu hỏi về Python Mixins có thể hữu ích nói chung. Tôi chỉ sử dụng các mô hình Django vì đó là trường hợp sử dụng mà tôi quen thuộc nhất.Django Model Mixins: kế thừa từ mô hình.Model hoặc từ đối tượng?

Một mixin có được kế thừa từ lớp được thiết kế để kết hợp với hoặc từ 'đối tượng' không?

Ví dụ bằng mã, điều gì là chính xác hơn hoặc tốt hơn, hoặc tốt hơn tùy thuộc vào những gì bạn muốn đạt được?

này

class TaggingMixin(models.Model): 
    tag = models.ForeignKey(Tag) 

    class Meta: 
     abstract = True 

class MyModel(models.Model, TaggingMixin): 
    title = models.CharField(max_length=100) 

Hoặc này:

class TaggingMixin(object): 
    tag = models.ForeignKey(Tag) 

    class Meta: 
     abstract = True 

class MyModel(models.Model, TaggingMixin): 
    title = models.CharField(max_length=100) 

Tôi nghĩ rằng kế thừa từ đối tượng là đúng cách. Nhưng tôi nhìn thấy ví dụ về trường hợp đầu tiên trên tất cả các mạng ...

EDIT: Tôi đã di chuyển theo tôi lên câu hỏi cho một câu hỏi riêng biệt: Django Abstract Models vs simple Python mixins vs Python ABCs

Trả lời

6

này trông giống như một công việc cho một abstract model.

EDIT:

Đó là không mixins cho mỗi gia nhập. Hay đúng hơn, họ không cần phải như thế. Bạn có thể lấy trực tiếp từ một mô hình trừu tượng.

+1

Err, vâng bạn đúng, đây là một công việc cho một mô hình trừu tượng, trên thực tế tôi chỉ quên chúng trong mã: s Tôi đã thêm nó, nhưng bây giờ tôi bắt đầu trở nên bối rối hơn về câu hỏi của riêng tôi ... – hopla

12

Tôi khuyên bạn nên thừa kế từ object. Bằng cách đó bạn có thể đảm bảo rằng nó chỉ cung cấp các phương thức và thuộc tính mà bạn thực sự xác định rõ ràng.

Ngoài ra, bạn nên luôn đảm bảo rằng bạn đặt lớp mixin trước tiên khi xác định lớp bê tông của bạn. Các quy tắc phân giải của Python có nghĩa là các siêu lớp được tìm kiếm theo thứ tự định nghĩa của chúng trong khai báo lớp và độ phân giải dừng lại khi tìm thấy một thuộc tính phù hợp. Vì vậy, nếu mixin của bạn định nghĩa một phương thức cũng được xác định bởi lớp cha chính, thì phương thức mixin của bạn sẽ không được tìm thấy.

+11

Ngoại trừ phép thuật metaclass có thêm trường không hoạt động nếu lớp mixin của bạn không kế thừa từ 'models.Model' (hoặc cụ thể hơn, không có' __metaclass__' được yêu cầu). –

+2

Thừa kế từ đối tượng không hoạt động đối với tôi. Xem: http://stackoverflow.com/questions/17343867/does-south-handle-model-mixins – utapyngo

+2

đối tượng kế thừa KHÔNG phải là cách tốt cho django. vì django makemigrations không thể nhận ra nó. các tệp di chuyển không chứa các tệp được lưu. – 9nix00

3

Khi bạn được thừa hưởng từ đối tượng Python đồng bằng Nam không tạo ra một sự chuyển đổi nên bạn không thể sử dụng phương pháp này

+0

Nó không liên quan gì đến việc di cư ở miền nam. –

+0

Tôi có nghĩa là cách tiếp cận không chơi tốt với miền Nam mà là một vấn đề lớn đối với tôi – kharandziuk

45

Django hiện rất nhiều phép thuật meta khi nói đến các lớp học mô hình của nó, vì vậy tiếc là phương pháp thông thường để mixins như đề xuất trong câu trả lời của Daniel Roseman - nơi họ kế thừa từ object - không hoạt động tốt trong vũ trụ Django.

Cách đúng để cấu trúc mixins của bạn, bằng cách sử dụng ví dụ được cung cấp, sẽ là:

class TaggingMixin(models.Model): 
    tag = models.ForeignKey(Tag) 

    class Meta: 
     abstract = True 

class MyModel(TaggingMixin): 
    title = models.CharField(max_length=100) 

Những điểm quan trọng ở đây là:

  • mixins kế thừa từ model.Model nhưng được cấu hình như một lớp trừu tượng.
  • Vì mixin kế thừa từ model.Model, mô hình thực tế của bạn nên không phải là được kế thừa từ nó. Nếu bạn làm như vậy, điều này có thể kích hoạt một ngoại lệ của lệnh phân giải phương thức nhất quán.
+1

Điều này sẽ dẫn đến 'LoạiError: Không thể tạo một thứ tự độ phân giải phương thức nhất quán (MRO)'. Làm 'lớp MyModel (TaggingMixin):' thay thế. Xem http://stackoverflow.com/q/29214888/1627479 – Joren

+0

Cảm ơn @Joren. Đã chỉnh sửa câu trả lời để phản ánh điều này. – jsdalton

Các vấn đề liên quan