2016-11-23 17 views
0

私はこれについてあなたのアドバイスを得ることができれば幸いです。逆関係で多対多キーのカウントを取得するにはどうすればよいですか?

トッピングに多対多の関係を持つピザモデルを使用している場合、ピザのトッピングの数を簡単に取得できます。

# models.py 
class Pizza(models.Model): 
    toppings = models.ManyToManyField(Topping) 

class Topping(models.Model): 
    name = models.CharField(max_length=255, null=True, blank=True) 

# admin.py 
@admin.register(Pizza) 
class PizzaAdmin(admin.ModelAdmin): 
    list_display = ['topping_count'] 

    def topping_count(self, pizza): 
     return pizza.toppings.count() 

ただし、多対多の前方関係をトッピングに移動すると、すべてが破損します。

# models.py 
class Pizza(models.Model): 
    pass 

class Topping(models.Model): 
    pizzas = models.ManyToManyField(Pizza) 

逆の関係でトッピングカウントを取得できるように、PizzaAdminのトッピングカウントを更新するにはどうすればよいですか?

ありがとうございます。

答えて

2

逆の関係が小文字モデル名+ _set使用しています。逆のカウントを取得します

class Topping(models.Model): 
    pizzas = models.ManyToManyField(Pizza, related_name='toppings') 
1

@admin.register(Pizza) 
class PizzaAdmin(admin.ModelAdmin): 
    list_display = ['topping_count'] 

    def topping_count(self, pizza): 
     return pizza.topping_set.count() 

また、あなたは現在の管理コードを維持し、関連する名前を変更することができます関係をpizza.topping_set.count()

1

あなたがトッピングを数える方法は、トッピングごとに別々のDBクエリを実行するという点で非効率的です。私はannotateを利用することを示唆している:

@admin.register(Pizza) 
class PizzaAdmin(admin.ModelAdmin): 
    list_display = ['topping_count'] 

    def get_queryset(self, request): 
     qs = super(PizzaAdmin, self).get_queryset(request) 
     return qs.annotate(topping_count=Count('topping_set'))    

    def topping_count(self, pizza): 
     return pizza.topping_count 

説明:annotateは管理者の各Pizzaためtopping_countを設定します。次に、PizzaAdmin.topping_countはインスタンスからtopping_countの値を取得します。

それはピザの数の無条件に一度だけあなたのデータベースに触れる必要がありますように。

関連する問題