Какова правильная модель для уменьшения логики в этой ситуации? - PullRequest
2 голосов
/ 25 февраля 2011

Я создаю модель, в которой два игрока участвуют в соревновании. Я склоняюсь к этой модели:

def match(models.Model):
    player = ForeignKey(Player)
    opponent = ForeignKey(Player)
    score = PositiveSmallIntegerField()
    games_won = PositiveSmallIntegerField()
    games_lost = PositiveSmallIntegerField()
    won_match = BooleanField()

Однако есть статистика, и для того, чтобы найти подходящую запись для оппонента, потребуется еще одно нажатие, если я захочу полностью описать матч.

В качестве альтернативы я мог бы настроить модель для включения полной статистики:

def match(models.Model):
    home_player = ForeignKey(Player)
    away_player = ForeignKey(Player)
    home_player_score = PositiveSmallIntegerField()
    away_player_score = PositiveSmallIntegerField()
    ...

Но это выглядит одинаково плохо, поскольку мне пришлось бы сделать два логических набора для одного игрока (чтобы найти его оценки, когда он home_player и его оценки, когда он away_player ). 1013 *

Последний вариант - сделать две вставки на матч, с полной статистикой и сохранить избыточные данные в таблице.

Кажется, что есть лучший способ, и поэтому я опрашиваю SO .

Ответы [ 3 ]

1 голос
/ 25 февраля 2011

Идентификатор идет с первой моделью и использует select_related(), чтобы избежать дополнительных вызовов в БД.

1 голос
/ 25 февраля 2011

Если вы хотите уменьшить избыточность и поддерживать последовательность логики ...

Match: - id
- имя

Match_Player: (2 записи на матч)
- match_id
- player_id
- is_home

Match_Player_Score:
- match_id
- player_id
- оценка

0 голосов
/ 26 февраля 2011

Я бы не использовал избыточные данные в базе данных. Это оставляет открытой возможность того, что данные базы данных станут внутренне противоречивыми и все испортит.

Используйте одну запись на матч, как во втором примере. Если вы планируете заранее, вы можете легко выполнить два набора логики. Посмотрите на модели прокси . Это может быть элегантный способ сделать так, чтобы вся ваша логика ссылалась на поля данных через методы доступа, такие как get_my_score и get_opponent_score. Затем создайте класс Proxy Model, который будет меняться как дома, так и далеко.

class match(models.Model):

    def get_my_score(self):
        return self.home_player_score

    def get_opponent_score(self):
        return self.away_player_score

    def did_i_win(self):
        return self.get_my_score() > self.get_opponent_score()


class home_player_match(match):
    class Meta:
        proxy = True

    def get_my_score(self):
        return self.away_player_score

    def get_opponent_score(self):
        return self.home_player_score

Или, может быть, вы хотите, чтобы две прокси-модели имели нейтральные имена в классе базовой модели. Проблема этого подхода заключается в том, что я не знаю, как преобразовать класс из одной модели прокси в другую без перезагрузки из базы данных. Вы хотите "rebless", как в Perl. Вы могли бы сделать это, используя сдерживание, а не наследование. Или, может быть, просто флаг в классе-обертке (не хранится в базе данных), указывающий, менять или нет поля. Но я бы порекомендовал какое-то подобное решение - решите сложные вещи в коде и не позволяйте базе данных стать непоследовательной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...