2010-07-21 88 views
2

我有一個多模型,具有不同的OneToOne關係,從不同的模型到單個父代。考慮下面這個例子:Django多模型:跟蹤關係

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

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

class Shop(models.Model): 
    place = models.OneToOneField(Place) 
    ... 

不管上面的模型是有道理的在真實的生活場景,一個人怎麼能確定是否放置的對象有任何其他機型的關係,在Django看法?

回答

1

在模板中,你可以說

{% if place.restaurant %} 
    <!-- stuff goes here --> 
{% endif %} 

這樣做的原因是,OneToOneField項實際創建它們所引用的模型的屬性。在正常的Python代碼中,如果沒有定義餐廳,則說place.restaurant會引發異常,但模板會吞噬這些異常。

如果你需要做這樣的事情在Python代碼,最簡單易懂的方式是/將其包裝在一個嘗試except塊:

place = Place.objects.all()[0] 
try: 
    restaurant = place.restaurant 
    # do something with restaurant 
except ObjectDoesNotExist: 
    # do something without restaurant 

編輯:正如我所說的我的評論,如果你只想要一個Place是一個RestaurantShop但從來都沒有,那麼你不應該使用OneToOneField而應該使用model inheritance

假設一個Place可以有兩個或兩個以上的其他可能性,我建議做這樣的事情:

class Place(Model): 
    # define your fields here 

    # you could generate this automatically with trickery 
    OTHER_MODELS = ["restaurant", "shop"] 

    @property 
    def relationships(self): 
     if not hasattr(self, "_relationships"): 
      self._relationships = {} 
      for attr in OTHER_MODELS: 
       try: 
        self._relationshops[attr] = getattr(self, attr) 
       except ObjectDoesNotExist: 
        pass 
     return self._relationships 

以上先給你說place.relationships並取回一個看起來像

{"restaurant": <Restaurant Object>, "shop": <Shop Object>} 
字典

雖然其中一個或兩個可能會丟失,這取決於它們是否存在。與每次改變OneToOneField關係時必須捕捉可能的例外情況相比,這樣做更容易。

+0

那去,如果沒有一個地點對象即店鋪和餐廳多種可能的方式。否則你必須遍歷每一個「子模型」。或者我錯過了什麼? – msebai 2010-07-21 17:11:58

+0

@ msebai:是的,你必須重複其他的可能性。如果你的設計要求'Place'只能是'Restaurant'或者'Shop'而不是兩個,那麼你不應該使用'OneToOneField',而應該使用模型繼承:http://docs.djangoproject。 com/en/1.2/topics/db/models /#model-inheritance – 2010-07-21 17:16:09

+1

我想繼承在這裏有很多意義。我只需要了解django如何在數據庫級別對待它。非常感謝您的時間。 – msebai 2010-07-21 17:27:08

0

因爲Restaurant有一個外鍵指向Place,它留下的類related name場,使指向的類(Place)可以找到它的內容:

# python 
import yourproject.settings 
from django.db.models.base import ObjectDoesNotExist 
try: 
    r = place.restaurant_set.get() 
    do_something(r.restaurant_field) 
except ObjectDoesNotExist: 
    print "place has no restaurant" 

而從模板,假設你從你的情況下以某種方式訪問​​placeobject

{% with placeobject.restaurant_set.get as r %} 
    {% if r %} 
    {{ r.restaurant_field }} 
    {% else %} 
    No restaurant 
    {% endif %} 
{% endwith %}