-1

I am getting the error below. Any help is appreciated. I am probably missing something very important from the documentation.

Kindly point out my mistake if you see it and enlighten me about many to many relations from Django. From the error presented does it mean that the .add() function cannot be used on querysets?

Traceback

Internal Server Error: /7/
Traceback (most recent call last):
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 124, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\music\songs\views.py", line 141, in Playlist_Add
    playlist.song.add(song)
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\related_descriptors.py", line 926, in add
    self._add_items(self.source_field_name, self.target_field_name, *objs)
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\related_descriptors.py", line 1073, in _add_items
    '%s__in' % target_field_name: new_ids,
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\query.py", line 844, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\query.py", line 862, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\sql\query.py", line 1263, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\sql\query.py", line 1287, in _add_q
    split_subq=split_subq,
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\sql\query.py", line 1225, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\sql\query.py", line 1096, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\lookups.py", line 20, in __init__
    self.rhs = self.get_prep_lookup()
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\related_lookups.py", line 59, in get_prep_lookup
    self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\related_lookups.py", line 59, in <listcomp>
    self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
  File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\__init__.py", line 965, in get_prep_value
    return int(value)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'QuerySet'
[16/Apr/2020 23:06:55] "GET /7/ HTTP/1.1" 500 127314

models.py

class Playlist (models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
    song = models.ManyToManyField(Song)

views.py

def Playlist_Add(request, id):
    song = Song.objects.filter(id=id)
    playlist, created = Playlist.objects.get_or_create(user=request.user)
    #playlist.save()
    playlist.song.add(song)
    return redirect('home:home')

urls.py

path('<int:id>/', views.Playlist_Add, name='playlist_add'),

templates

<footer class="w3-container w3-blue">
    <a href="{% url 'playlist_add' id=obj.id %}">
    <button type="button" class="btn btn-info">+ To Playlist</button>
    </a>
    <h5>last edited:&nbsp {{objects.timestamp}}</h5>
  </footer>
HAN YAO FOONG
  • 137
  • 1
  • 8

1 Answers1

0

Your song is not a single song, it is a QuerySet of songs, it thus can contain zero, one or more songs. Because you filter on a primary key, it can only contain zero or one Songs, but regardless, it is still a collection.

You can fix this by using a .get(..) over a .filter(), or better, a get_object_or_404(..):

from django.shortcuts import get_object_or_404

def Playlist_Add(request, id):
    song = get_object_or_404(Song, id=id)
    playlist, created = Playlist.objects.get_or_create(user=request.user)
    #playlist.save()
    playlist.song.add(song)
    return redirect('home:home')

Note: A GET request is not supposed to have side-effects, hence constructing objects when a user makes a GET request, is not compliant with the HTTP standard. Therefore it might be better to turn this into a POST request.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555