2017-02-13 49 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”语句。最好尝试并避免必须遍历地方然后?也许会立刻将用户分支到“餐馆”部分......只是在这里大声思考。 –