Reputation: 70
I am developing a music web application where I am trying to calculate the number of times a song was played. When the play button is clicked, a function called getLink()
is called. Here, I try to use get_or_create
to update the PlayCount
model, like so.
h = PlayCount.objects.all()
if len(h) == 0:
u = PlayCount.objects.get_or_create(
user=request.user.username,
song=song,
plays=1,
)[0]
u.save()
else:
flag = False
for i in h:
if i.song == song:
u = PlayCount.objects.get_or_create(
user=request.user.username,
song=song,
plays=plays + 1,
)[0]
u.save()
flag = True
break
else:
pass
if flag is False:
u = PlayCount.objects.get_or_create(
user=request.user.username,
song=song,
plays=1,
)[0]
u.save()
else:
pass
However, when I enter the else loop, 127.0.0.1:8000
returns play is not defined
.
How may I proceed?
Upvotes: 0
Views: 366
Reputation: 20672
I don't understand why you loop through all the PlayCount
objects when all you need is to find the one for the specific user
and song
.
Note also that get_or_create
will only find the specific object that matches all the parameters you pass to it, so get_or_create(user=..., song=..., plays=...)
will try finding the one with the exact number of plays you specify which isn't what you want.
You only need to do this:
from django.db.models import F
play_counter, created = PlayCount.objects.get_or_create(
user=request.user,
song=song,
defaults={'plays': 1})
if not created:
play_counter.plays = F('plays') + 1
play_counter.save()
So here we first fetch or create the counter for the particular song and user. If we create it, we set plays
to 1 by setting it in the defaults
parameter.
Then, if it is not created (i.e. it's an existing one), we increment plays
by 1, using the F
expression, which ensures it's updated in the database directly (and there's no risk of database inconsistency due if another request is updating the same value).
Upvotes: 2