1. Tak naprawdę nie dostać żadnego dziedziczenia Pythona, czyli nie można dziedziczyć/metod nadpisywania lub atrybutów z klasy modelu Place
w swojej klasie Restaurant
:
na przykład:
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
oznacza to, że w celu otrzymania name
z restauracji nie można zrobić a_restaurant.name
, trzeba by śledzić link: a_restaurant.place.name
Należy również pamiętać, że podczas zapytań do Place
obiekt z powiązanym Restaurant
.
a_restaurant.save()
Place.objects.get(pk=a_restaurant.pk) # won't work
Trzeba by napisać:
a_restaurant.save()
Place.objects.get(restaurant__pk=a_restaurant.pk)
2 i 3. są prawie takie same. Otrzymujesz z nich prawdziwe dziedzictwo Pythona.
a_restaurant = Restaurant()
a_restaurant.get_x() # would actually work and print 'x'
Twój model klasy Restaurant
dziedziczy wszystko od Place
: pola modelu, normalne atrybuty instancji/klasa, menedżerów, metod ... i można również zastąpić prawie nic o nich: Nie można zastąpić atrybuty pól , to nie jest obsługiwane.
Teraz można uzyskać wartości pól bezpośrednio z modelu macierzystego: a_restaurant.name
, ponieważ są one dziedziczone.
Ponieważ z tymi realizacji Restaurant
jest również Place
można wyszukać na Place
obiektu z Restaurant
danych:
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
różnicy między 2 i 3 jest łatwiej sprawdzić, czy podasz inną nazwę pola:
class Place(models.Model):
name = models.CharField(max_length=50)
class Restaurant(Place):
where = models.OneToOneField(Place, parent_link=True)
serves_pizza = models.BooleanField()
działa dokładnie tak samo, ale w celu uzyskania miejsca rodzicem Restaurant
nazwa atrybutu jest where
:
the_place = a_restaurant.where
z byłby:
the_place = a_restaurant.place_ptr
Te środki, które place = models.OneToOneField(Place, parent_link=True)
tylko zmiany nazwa odsyłacza do instancji modelu nadrzędnego. Domyślna nazwa to '{lowercase_model_name}_ptr'
.
Ostatni przykład:
Z :
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]
Z 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]
Mam nadzieję, że to pomaga. Trochę za długo rośnie:/
Chcę rozszerzyć strukturę wbudowanych serwisów Model witryny z dodatkowymi polami i podjęcie decyzji, która metoda jest najlepsza. – kissgyorgy