Player
、League
、およびの3 つのモデルがありLeaguePlayer
ます。LeaguePlayer
は との外部キー関係とPlayer
への外部キー関係を持っていLeague
ます。Player
いくつかのカスタム クエリがあります。次に例を示します。
Player.objects.by_position('catcher')
、 また
Player.objects.by_position(position='batter', exclude='catcher')
、 また
Player.objects.by_best_position('shortstop')
.
Player
に対してフィルタリングするときに、カスタム クエリを使用できるようにしたいと考えていますLeaguePlayer
。例は次のようになります:カスタム フィルタLeaguePlayer.objects.by_position('catcher')
を使用します。したがって、フィールドがある場合、次のようなことをしたいと思います:Player
by_position
LeaguePlayer
player_value
LeaguePlayer.objects.by_position('catcher').filter('player_value__gt'=100)
からフィルターを何らかの方法で「継承」する方法がない場合Player
はLeaguePlayer
? または、そうでない場合、このタイプのフィルタリングを簡単に作成できるように、モデルを整理する別の方法はありますか?
@yuvi、私の質問の背後にあるコード:
from django.db import models
from model_utils.managers import PassThroughManager
from player.models import Positions
class League(models.Model):
name = models.CharField(verbose_name="League name", max_length=50, unique=True)
number_of_teams = models.IntegerField(
verbose_name="Number of teams in your league",
choices=[(i, i) for i in range(6, 19)],
blank=False, default=10
)
...
class PlayerQuerySet(models.query.QuerySet):
def exclude_position(self, exclude=None):
non_excluded_positions = [...]
return self.filter(all_positions__in=non_excluded_positions).distinct()
def by_position(self, positions=None, exclude=None):
player_set = self
if exclude is not None:
player_set = self.exclude_position(exclude)
if positions is None:
return player_set.distinct()
return player_set.filter(all_positions__in=positions).distinct()
class PlayersManager(PassThroughManager):
def get_query_set(self):
return PlayerQuerySet(self.model, using=self._db)
class Players(models.Model):
name = models.CharField(max_length=30)
primary_position = models.ForeignKey(Positions, related_name='primary')
all_positions = models.ManyToManyField(Positions, related_name='positions')
objects = PlayersManager()
class LeaguePlayerQuerySet(models.query.QuerySet):
def custom_query(self):
return some filtered version of self
class LeaguePlayerManager(PassThroughManager):
def get_query_set(self):
return LeaguePlayerQuerySet(self.model, using=self._db)
class LeaguePlayer(models.Model):
league = models.ForeignKey(League)
player = models.ForeignKey(Players)
player_value_property = models.FloatField(null=True)
...
objects = LeaguePlayerManager()
@property
def player_value(self):
if not self.player_value_property:
self.player_value_property = calculate value based on self.league and self.player
self.save()
return self.player_value_property
PassThroughManager の詳細については、 https ://bitbucket.org/carljm/django-model-utils/overview を参照してください。つまり、カスタム QuerySet メソッドの連鎖が可能になります。