1

小さな投票機能をリファクタリングしようとしています。モデルフィールドが異なるだけで、ほぼ同じことを行う2つのものがあります。投票者は、気に入った曲に星を追加したり、気に入らなかった曲にフラグを追加したりできます。その後、有権者は多対多の関係を介して曲に関連付けられるため、その曲にすでに投票したかどうかを判断できます。その場合、星 (またはフラグ) が歌から削除され、有権者と歌の間の関係も削除されます。

星を追加または削除する関数は次のとおりです。

# models.py
class UserProfile(models.Model):
    user = models.ForeignKey(User, unique = True, related_name = 'profile')
    liked_songs = models.ManyToManyField('Song', blank = True, null = True)
    disliked_songs = models.ManyToManyField('Song', blank = True, null = True)

class Song(models.Model):
    song_id = models.CharField(max_length = 36, primary_key = True)
    last_accessed = models.DateTimeField()
    stars = models.IntegerField(max_length = 5, default = 0)
    flags = models.IntegerField(max_length = 5, default = 0)

# views.py
def vote(request, song_id, task):  # 'task' should be either 'stars' or 'flags'
    song = Song.objects.get(song_id = song_id)
    voter = request.user.get_profile()

    # Voter does not already like the song
    if not voter.liked_songs.filter(song_id = song.song_id):  # (*)
        try:
            # Increase vote, set 'last_accessed', add Song to UserProfile.liked_songs
            Song.objects.filter(song_id = song_id).update(
                stars = F('stars') + 1,  # (*)
                last_accessed = datetime.datetime.now()
            )
            voter.liked_songs.add(song)  # (*)
        except:
            raise
    else:
        try:
            # Decrease vote, set 'last_accessed', remove Song from UserProfile.liked_songs
            Song.objects.filter(song_id = song_id).update(
                stars = F('stars') - 1,  # (*)
                last_accessed = datetime.datetime.now()
            )
            voter.liked_songs.remove(song)  # (*)
        except:
            raise
    return "Done."

フラグを追加または削除する関数は、マークされた (*) 行を除いてまったく同じです。

if not voter.disliked_songs.filter(song_id = song.song_id)
flags = F('flags') + 1,
flags = F('flags') - 1,
voter.disliked_songs.add(song)
voter.disliked_songs.remove(song)

ここで最初の質問です。曲の好き嫌いを 1 つの機能だけで判断するにはどうすればよいですか? 引数は既に導入しましたが、Song モデルには「タスク」というフィールド名がないため、task書ききれないようです。task = F('task') + 1,

stars = F('stars') + 1,おまけの質問:との唯一の違いstars = F('stars') - 1,は、演算子 (+または-) です。変数に演算子を含める方法はありtask = F('task') myoperator 1,ますか?

4

1 に答える 1

0

おまけの質問の答え: 次の例のように、引数として演算子を受け取り、引数に基づいて式を評価する関数を持っていないのはなぜですか?

>>> def f(op):
...  return (eval("3"+op+"2"))
>>> f("+")
5
>>> f("-")
1
于 2012-05-28T08:52:00.337 に答える