我正在尝试重构我的小投票功能。我有两个几乎完全相同的东西,只有不同的模型字段。如果喜欢的话,选民可以为歌曲添加星星,如果他们不喜欢,他们可以为歌曲添加标记。然后选民通过许多关系与歌曲相关联,因此可以确定他们是否已经对该歌曲进行了投票。如果是这样,歌曲中的星号(或旗帜)将被删除,选民和歌曲之间的关系也会被删除。
这是添加或删除星星的功能:
# 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)
现在,这是我的第一个问题:我只需要使用一个功能来喜欢和不喜欢一首歌?我已经引入了参数task
但我似乎无法写task = F('task') + 1,
,因为Song模型中没有字段名称'task'。
加分问题:stars = F('stars') + 1,
和stars = F('stars') - 1,
之间的唯一区别是运算符(+
或-
)。有没有办法让变量中的运算符,即task = F('task') myoperator 1,
?
答案 0 :(得分:0)
答案奖励问题:为什么你没有一个函数接受运算符作为参数并根据参数?评估表达式,如下例所示:
>>> def f(op):
... return (eval("3"+op+"2"))
>>> f("+")
5
>>> f("-")
1