I have a model 'Playlist' with an attribute 'private' that can be True or False (and therefore private or public). I want to use the @login_required decorator only if 'private = False', but can't figure out how to achieve this result. Here is my models.py file:
class Playlist(models.Model):
"""Allow a user to create a customized list of songs."""
name = models.CharField(max_length=100)
image = models.ImageField(upload_to='playlists/%Y/%m/%d', blank=True, null=True)
songs = models.ManyToManyField('Song')
description = models.TextField(blank=True, null=True, max_length=1000)
date_added = models.DateTimeField(auto_now_add=True)
private = models.BooleanField()
def __str__(self):
"""String for representing the model object."""
return self.name
def get_absolute_url(self):
"""Returns the url to access a detail record for this song."""
return reverse('playlist-detail', args=[str(self.id)])
And my views.py file:
def playlist(request, playlist_id):
"""Show a single playlist and associated data."""
playlist = Playlist.objects.get(id=playlist_id)
songs = playlist.songs.all()
for song in songs:
if song.url:
song.video_id = song.url.replace("https://www.youtube.com/watch?v=", "")
context = {'playlist': playlist, "playlist_songs": songs}
return render(request, 'great_songs_app/playlist.html', context)
I stumbled across a similar thread but there was no answer to the problem:Conditionally apply login_required decorator in Django
I imagine code looking something like what the OP posted, with the view function being preceded by:
if playlist.private == True:
@login_required
...
But obviously that won't work. Any ideas?
Rather than trying to apply @login_required
, you could simply let the view undecorated and do something like the following, checking whether the user is authenticated:
from django.shortcuts import redirect
from django.conf import settings
def playlist(request, playlist_id):
"""Show a single playlist and associated data if user is authenticated."""
playlist = Playlist.objects.get(id=playlist_id)
if not playlist.private or (playlist.private and request.user.is_authenticated):
songs = playlist.songs.all()
for song in songs:
if song.url:
song.video_id = song.url.replace("https://www.youtube.com/watch?v=", "")
context = {'playlist': playlist, "playlist_songs": songs}
return render(request, 'great_songs_app/playlist.html', context)
else:
redirect(settings.LOGIN_URL)