Логика кнопок SQLAlchemy, изменяющаяся с True на None на False

#python #flask-sqlalchemy

#python #flask-sqlalchemy

Вопрос:

Я надеюсь получить некоторую помощь в этом. Я считаю, что моя логика ошибочна.

У меня есть приложение, в котором вы можете оценивать разные статьи на основе релевантности после поиска. Кнопки переключения являются релевантными и не релевантными. Это делается для определения того, имеет ли конкретная статья отношение к поиску, не имеет отношения к поиску или не определено.

Базовая функциональность кнопок:

Когда ни одна из кнопок не выбрана:

  • Пользователь нажимает Relevant -> Установить RelevantFlag.state значение True
  • Пользователь нажимает Не релевантно -> Установить RelevantFlag.state значение False

Когда выбрана соответствующая кнопка:

  • Пользователь нажимает Relevant -> Установить RelevantFlag.state значение None
  • Пользователь нажимает Не релевантно -> Установить RelevantFlag.state значение False

Когда выбрана не соответствующая кнопка:

  • Пользователь нажимает Relevant -> Установить RelevantFlag.state значение True
  • Пользователь нажимает Не релевантно -> Установить RelevantFlag.state значение None

Новая RelevantFlag запись будет добавляться каждый раз, когда пользователь нажимает кнопку. При выборе соответствующей кнопки, а затем при повторном ее выборе кнопка отключается. Например, дважды нажать соответствующую и распечатать записи:

<'RelevantFlag:True'> <'RelevantFlag:None'>

Когда пользователь нажимает соответствующие 3 раза, записи должны быть:

<'RelevantFlag:True'> <'RelevantFlag:None'> <'RelevantFlag:True'>

Вместо этого я получаю

<'RelevantFlag:True'> <'RelevantFlag:None'> <'RelevantFlag:None'>

Вот класс модели, с которым я работаю:

 class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    def mark_relevant(self, research, article):
        # If nothing is selected OR
        # NotRelevant is selected, set True state
        if (not self.has_marked_relevant(research, article) or
            self.has_marked_not_relevant(research, article)):
            relevant = RelevantFlag(
                user_id=self.id,
                research_id=research.id,
                article_id=article.id,
                state=True
            )
            db.session.add(relevant)

        # If Relevant already selected, set back to None
        elif self.has_marked_relevant(research, article):
            relevant = RelevantFlag(
                user_id=self.id,
                research_id=research.id,
                article_id=article.id,
                state=None
            )
            db.session.add(relevant)

    def mark_not_relevant(self, research, article):
        # If nothing is selected OR
        # Relevant is selected, set False state
        if (not self.has_marked_not_relevant(research, article) or
            self.has_marked_relevant(research, article)):
            not_relevant = RelevantFlag(
                user_id=self.id,
                research_id=research.id,
                article_id=article.id,
                state=False
            )
            db.session.add(not_relevant)

        # If Not Relevant already selected, set back to None
        elif self.has_marked_not_relevant(research, article):
            not_relevant = RelevantFlag(
                user_id=self.id,
                research_id=research.id,
                article_id=article.id,
                state=None
            )
            db.session.add(not_relevant)

    def has_marked_relevant(self, research, article):
        return RelevantFlag.query.filter(
            RelevantFlag.user_id == self.id,
            RelevantFlag.research_id == research.id,
            RelevantFlag.article_id == article.id,
            RelevantFlag.state).count() > 0

    def has_marked_not_relevant(self, research, article):
        return RelevantFlag.query.filter(
            RelevantFlag.user_id == self.id,
            RelevantFlag.research_id == research.id,
            RelevantFlag.article_id == article.id,
            RelevantFlag.state == False).count() > 0
  

И модель RelevantFlag

 class RelevantFlag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    article_id = db.Column(db.Integer, db.ForeignKey('article.id'))
    state = db.Column(db.Boolean)

    def __repr__(self):
        return '<Relevant: {0}:{1}>'.format(
            self.user_id,
            self.state
            )
  

Я застрял на том, как включить двухкнопочные переключатели, которые создают записи с разными состояниями. Любые рекомендации будут оценены!

Комментарии:

1. has_marked_* Методы, похоже, относятся ко всей истории, а не к текущему состоянию кнопки. Это намеренно?

2. Ах, это не намеренно. Похоже, моя проблема заключается в has_marked_ методах

3. Установите временную метку для записей флага и выберите самую последнюю?

4. Это проще и быстрее, если вы замените .count() > 0 на .exists() . Что, если я попрошу вас посчитать песчинки на пляже, только чтобы поинтересоваться, есть ли они? Я бы сэкономил вам много времени, чтобы придумать точное число, если бы я просто сказал вам остановиться, как только вы нашли одно зерно

5. Попробуйте заменить RelevantFlag.state==False на RelevantFlag.state==sqlalchemy.false() . Это два разных объекта — и я думаю, что это портит ваш запрос