( Cập nhật : Đối với Django 1.2 và mới hơn, có thể làm theo select_related truy vấn trên quan hệ OneToOneField ngược (và do đó giảm phân cấp thừa kế), có một kỹ thuật tốt hơn có sẵn mà không yêu cầu thêm real_type
lĩnh vực trên mô hình mẹ Nó có sẵn như. InheritanceManager trong dự án django-model-utils .)
Cách thông thường để thực hiện việc này là thêm ForeignKey vào ContentType trên mô hình Parent để lưu trữ kiểu nội dung của lớp "lá" thích hợp. Nếu không có điều này, bạn có thể phải thực hiện khá nhiều truy vấn trên bảng con để tìm cá thể, tùy thuộc vào cây kế thừa của bạn lớn như thế nào. Đây là cách tôi đã làm điều đó trong một dự án:
from django.contrib.contenttypes.models import ContentType
from django.db import models
class InheritanceCastModel(models.Model):
"""
An abstract base class that provides a ``real_type`` FK to ContentType.
For use in trees of inherited models, to be able to downcast
parent instances to their child types.
"""
real_type = models.ForeignKey(ContentType, editable=False)
def save(self, *args, **kwargs):
if self._state.adding:
self.real_type = self._get_real_type()
super(InheritanceCastModel, self).save(*args, **kwargs)
def _get_real_type(self):
return ContentType.objects.get_for_model(type(self))
def cast(self):
return self.real_type.get_object_for_this_type(pk=self.pk)
class Meta:
abstract = True
Điều này được thực hiện như một lớp cơ sở trừu tượng để làm cho nó có thể tái sử dụng; bạn cũng có thể đặt các phương thức này và FK trực tiếp vào lớp cha trong hệ thống phân cấp kế thừa cụ thể của bạn.
Giải pháp này sẽ không hoạt động nếu bạn không thể sửa đổi mô hình gốc. Trong trường hợp đó, bạn khá khó kiểm tra tất cả các lớp con theo cách thủ công.