2017-02-13 50 views
0

我需要幾個從一個基類繼承一對一關係的模型。在與Django的例子保持:有效地使用多表繼承(一對一關係)

from django.db import models 

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

class Restaurant(Place): 
    serves_hot_dogs = models.BooleanField(default=False) 
    serves_pizza = models.BooleanField(default=False) 

class Garage(Place): 
    car_brands_serviced = Models.ManyToManyField(Brands) 

class Boutique(Place): 
    for = Models.ChoiceField(choices=(("m", "men"), ("w", "women"), ("k","kids")) 

# etc 

現在我該怎樣有效地將各類場所的區分,當我在一個模板(或視圖功能)迭代呢?現在,我只看到這個解決方案(如果我要遍歷的地方,而不是兒童模特單獨):

for place in Place.objects.all(): 
    try: 
     r = place.restaurant 
     # Do restaurant stuff here 
    except ObjectDoesNotExist: 
     try: 
      g = place.garage 
      # Do garage stuff here 
     except ObjectDoesNotExist: 
      try: 
       b = place.boutique 
       # Do boutique stuff here 
      except ObjectDoesNotExist: 
       # Place is not specified 

甚至不知道如何將轉化爲一個模板,但是這個代碼看起來非常錯誤和低效。

作爲一種逃避,我想你可以在地方選擇一個地方來跟蹤哪個兒童模型是相關的,但這等同於危險的非規範化。

我在某種程度上否定了這一點?你怎麼做到這一點?

+0

甚至不知道如果加入' place_type'字段到Place是一個很糟糕的主意。確保它非規範化,但是如果場所類型的數量增加,它可以避免許多查找... –

回答

1

難道是喜歡簡單的東西:

models.py:

from django.db import models 

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

class Restaurant(Place): 
    serves_hot_dogs = models.BooleanField(default=False) 
    serves_pizza = models.BooleanField(default=False) 
    is_restaurant = True 

class Garage(Place): 
    car_brands_serviced = Models.ManyToManyField(Brands) 
    is_garage = True 

模板可以像這樣工作 - template.html:

{% for place in places %} 
{% if place.is_restaurant %} 
    <!-- Restaurant Stuff --> 
{% elif place.is_garage %} 
    <!-- Garage Stuff --> 
{% endif %} 
{% endfor %} 
+0

這可能是最好的解決方案。我唯一知道的其他選擇是使用:'hasattr(place,「garage」)' – themanatuf

+0

這是一個聰明的方法。我想沒有銀彈可以避免「if」或「try」語句。最好嘗試並避免必須遍歷地方然後?也許會立刻將用戶分支到「餐館」部分......只是在這裏大聲思考。 –