ميراث نموذج Django ، نماذج تصفية
-
21-09-2019 - |
سؤال
بالنظر إلى النماذج التالية: (لا تمانع في حقول النص هناك فقط للتوضيح)
class Base(models.Model):
field1 = models.TextField()
class Meta:
abstract=True
class Child1(Base):
child1_field = models.TextField()
class Child2(Base):
child2_field = models.TextField()
class Content(models.Model):
aso_items = models.ManyToManyField('Base')
وفقًا لهذه التعريفات ، يمكن ربط كائن المحتوى بأكثر من كائن أساسي ، على سبيل المثال. يمكن ربط مقابلة (= كائن المحتوى) بموسيقي (= child1 كائن) ، و filmdirector (= child2) ، إلخ.
الآن ، لسؤالي: هل من الممكن تصفية كائنات المحتوى وفقًا للنموذج الذي يشير إليه حقل ASO_ITEMS؟ مثال على ذلك: قل أنني أرغب في الحصول على QuerySet تحتوي على جميع كائنات المحتوى المرتبطة بكائن معين من Child1 (على سبيل المثال ، جميع المقابلات المرتبطة بالموسيقي بوب ديلان) ، كيف يمكنني تحقيق ذلك؟
علاوة على ذلك ، ماذا لو كنت أرغب في مجموعة QuerySet التي تحتوي على جميع كائنات المحتوى المرتبطة بكائنات Child1؟ (على سبيل المثال ، جميع المقابلات المرتبطة بالموسيقيين) كيف يغير هذا التصفية؟
شكرًا مقدمًا: أواجه بعض المشكلات مع الفضاء الأبيض في المعاينة ، سامحني
المحلول
يجب عليك التحقق من قسم مستندات Django فيما يتعلق باستخدام related_name
لفصول القاعدة التجريدية. http://docs.djangoproject.com/en/dev/topics/db/models/#bebe-careful-with-relion-name
على حد تعبير المستندات:
إذا كنت تستخدم
related_name
تنسب إلى Foreignkey أو Manytomanyfield ، يجب عليك دائمًا تحديد اسم عكسي فريد للحقل. هذا عادة ما يتسبب في وجود مشكلة في فئات الأساس المجردة ، حيث يتم تضمين الحقول في هذه الفئة في كل فئة من فئات الأطفال ، مع نفس القيم بالضبط للسمات (بما في ذلكrelated_name
) كل مرة.للتغلب على هذه المشكلة ، عندما تستخدم conference_name في فئة أساسية مجردة (فقط) ، يجب أن يكون جزء من الاسم هو السلسلة
%(class)s
. يتم استبدال هذا بالاسم المنخفض لفئة الطفل التي يتم استخدام الحقل فيها. نظرًا لأن كل فئة لها اسم مختلف ، سينتهي كل اسم ذي صلة.
باستخدام هذه المعلومات ، أوصي بنقل حقل M2M إلى الفئة الأساسية:
class Content(models.Model):
# Add remaining fields for Content
pass
class Base(models.Model):
field1 = models.TextField()
items = models.ManyToManyField(Content,related_name="%(class)s_related")
class Meta:
abstract=True
class Child1(Base):
child1_field = models.TextField()
class Child2(Base):
child2_field = models.TextField()
نصائح أخرى
يبدو أن علاقة أجنبية (أو Manytomany لهذه المسألة) مع فئة مجردة غير مسموح بها. أحصل على الخطأ التالي: "AssertionError: لا يمكن لـ Foreignkey تحديد علاقة مع الفئة المجردة".
يتمثل الحل المحتمل في تحديد الفئة الأساسية على أنها غير مجرى ، ولكن هذا يعني أنه يمكن للمرء أن ينظم نماذج من الفئة الأساسية. هذا ليس السلوك الذي أريده. (بعد كل شيء كان فئة مجردة) هل جاء شخص ما نفس المشكلة كيف قمت بحلها؟ أي بدائل؟
القي نظرة على http://www.djangoproject.com/documentation/models/generic_relations/ الذي يمر من خلال العلاقات العامة. سوف يتطابق نموذج المحتوى الخاص بك مع نموذج TaggedItem الخاص بهم ، وسيتوافق نموذجك الأساسي مع نموذجهم للحيوان/الخضار/المعدني (مع تمديد Child1 و Child2).
سيكون الحصول على جميع كائنات المحتوى لطفل واحد (على افتراض أنك ضبطت العلاقة بين المحتويات داخل القاعدة):
child_contents = childObject.contents.all()
وللحصول على جميع كائنات المحتوى لنموذج:
ctype = ContentType.objects.get_for_model(Child1)
all_child_contents = Content.objects.filter(content_type=ctype)