2017-02-13 6 views
0

基本クラスから1対1の関係で継承するいくつかのモデルが必要です。 Djangoの例を踏まえて:私はテンプレート(またはビュー機能)でそれらを反復するときマルチテーブルの継承(1対1の関係)を有効に使用

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 

それがテンプレートに変換しますが、このコードは非常に間違っていると非効率ですかさえわかりません。

エスケープとして、どの子モデルが関連しているかを追跡するための選択肢をPlaceで作成できますが、それは危険な非正規化に相当します。

私は何とかこれを思い描いていますか?これどうやってやるの?

+0

さえわかりませんplace_type'フィールドは、これ以上悪い考えです。確かにそれは非正規化ですが、場所の種類の数が増えると多くのルックアップを避けることができます。 –

答えて

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'文を避けるための銀色の弾丸はないと思う。ベストプラクティスを試してみよう。たぶんユーザーをすぐに「レストラン」セクションにブランチして...多分ここで大声で考えてみてください。 –