16

これらの実装の違いは何ですか? Django の違い (メタorderingget_latest_by属性の継承以外) は?

1.

# models.py
from django.db import models

class Place(models.Model):
    name = models.CharField(max_length=50)

class Restaurant(models.Model):
    place = models.OneToOneField(Place)
    serves_pizza = models.BooleanField()

2.

class Place(models.Model):
    name = models.CharField(max_length=50)

class Restaurant(Place):
    serves_pizza = models.BooleanField()

3.

class Place(models.Model):
    name = models.CharField(max_length=50)

class Restaurant(Place):
    place = models.OneToOneField(Place, parent_link=True)
    serves_pizza = models.BooleanField()
4

2 に答える 2

18

1.実際にはPythonの継承は得られません。つまりPlace、クラスのモデルクラスからメソッドまたは属性を継承/オーバーライドすることはできませんRestaurant:

例えば:

class Place(models.Model):
    name = models.CharField(max_length=50)

    def get_x(self):
        return 'x'

class Restaurant(models.Model):
    place = models.OneToOneField(Place)
    serves_pizza = models.BooleanField()

a_restaurant = Restaurant()
a_restaurant.get_x() # -> wouldn't work

これは、nameあなたができないレストランのを取得するa_restaurant.nameには、リンクをたどる必要があることを意味します:a_restaurant.place.name

Placeまた、関連するオブジェクトを照会する場合にも注意してくださいRestaurant

a_restaurant.save()
Place.objects.get(pk=a_restaurant.pk)  # won't work

あなたは書く必要があります:

a_restaurant.save()
Place.objects.get(restaurant__pk=a_restaurant.pk)

2および3。ほぼ同じです。これらを使用すると、実際の python 継承を取得できます。

a_restaurant = Restaurant()
a_restaurant.get_x() # would actually work and print 'x'

モデル クラスは、モデル フィールド、通常のインスタンス/クラス属性、マネージャー、メソッドなどRestaurantからすべてを継承しますPlace。また、これらのほとんどすべてをオーバーライドすることも できます。フィールド属性をオーバーライドすることはできません。これはサポートされていません。

したがって、フィールドの値を親モデルから直接取得できるようになりましたa_restaurant.name。これらは継承されているためです。

これらの実装でRestaurant a もであるため、データを含むオブジェクトをPlace照会できます。PlaceRestaurant

a_restaurant.save()
the_place = Place.objects.get(pk=a_restaurant.pk)  
# ^ this works now and returns the equivalent `Place` instance.
the_same_restaurant = the_place.restaurant

フィールドに別の名前を付けると、2 と 3の違いがわかりやすくなります。

class Place(models.Model):
    name = models.CharField(max_length=50)

class Restaurant(Place):
    where = models.OneToOneField(Place, parent_link=True)
    serves_pizza = models.BooleanField()

まったく同じように機能Restaurantしますが、属性名の親の場所を取得するにはwhere:

the_place = a_restaurant.where

2の場合は次のようになります。

the_place = a_restaurant.place_ptr

これらはplace = models.OneToOneField(Place, parent_link=True)、親モデル インスタンスへのリンクの名前のみを変更することを意味します。デフォルト名は です'{lowercase_model_name}_ptr'


最後の例:

1 : _

place1 = Place.objects.create(name='place_1')
place2 = Place.objects.create(name='place_2')
restaurant1 = Restaurant.objects.create(place=place1, serves_pizza=True)

print Place.objects.all() # prints [place1, place2]
print Restaurant.objects.all() # prints [restaurant1]

2-3 : _

place1 = Place.objects.create(name='place_1')
place2 = Place.objects.create(name='place_2')
restaurant1 = Restaurant.objects.create(name='place_3', serves_pizza=True)

print Place.objects.all() # prints [place1, place2, place3]
print Restaurant.objects.all() # prints [restaurant1]

これらが役立つことを願っています。少し長くなりすぎます:/

于 2013-08-18T00:21:33.080 に答える
3

1 - レストランを作成するには、場所を作成する必要があります。レストランを作成した後、それらをリンクした後、2 - レストランを作成すると、新しい場所が作成され、自動的にリンクされます。3 - 親リンクの名前を場所に変更しました。

コンテンツ タイプでモデル継承を使用すると、Place.objects.all() を反復処理するすべてのカフェ、レストラン、バーなどを一覧表示できます。

于 2013-08-17T20:16:09.230 に答える