【问题标题】:Direct assignment to the forward side of a many-to-many set is prohibited. Use songs.set() instead禁止直接分配到多对多集合的前端。改用 song.set()
【发布时间】:2020-03-21 21:59:21
【问题描述】:

我正在尝试将一首歌添加到我拥有的播放列表模型中,但它一直在说

禁止直接分配到多对多集合的前端。改用 song.set()。 我的播放列表模型代码:

class Playlist(models.Model):
    image = models.ImageField()
    name = models.CharField(max_length=100)
    artist = models.ForeignKey(User, on_delete=models.CASCADE)
    fav = models.BooleanField(default=False)
    songs = models.ManyToManyField(Music)
    slug = models.SlugField(editable=False, default=name)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('playlist-detail', kwargs={'pk': self.pk})

    @classmethod
    def add_music(cls, new_song):
        playlist, created = cls.objects.get_or_create(songs=new_song)
        playlist.songs.add(new_song)

    @classmethod
    def remove_music(cls, new_song):
        playlist, created = cls.objects.get_or_create(songs=new_song)
        playlist.songs.remove(new_song)

我的 Song 模型代码:

class Music(models.Model):
    image = models.ImageField()
    name = models.CharField(max_length=100)
    song = models.FileField(upload_to='musics/', blank=False, null=False)
    artist = models.ForeignKey(User, on_delete=models.CASCADE)
    fav = models.BooleanField(default=False)
    slug = models.SlugField(editable=False, default=name)
    lyrics = models.TextField(default="Unknown lyrics")
    genre = models.CharField(
        max_length=2,
        choices=GENRE,
        null=False,
        blank=False,
        default=""
    )

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('post-detail', kwargs={'pk': self.pk})

将歌曲添加到播放列表对象的我的视图方法

def add_to_playlist(request, operation, pk):
    new_song = Music.objects.get(pk=pk)
    if operation == 'add':
        Playlist.add_music(new_song)
    elif operation == 'remove':
        Playlist.remove_music(new_song)
    return redirect('/')

HTML代码:

 {% for i in music %}
  {% for v in playlist %}
     <a class="dropdown-item" href="{% url 'add_to_playlist' operation='add' pk=i.pk %}">Add to{{v.name}}</a>
   {% endfor %}  
 {% endfor %}

完全错误:

Traceback:

File "C:\Users\hooriaishtiaq\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\db\models\query.py" in get_or_create
  538.             return self.get(**kwargs), False

File "C:\Users\hooriaishtiaq\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\db\models\query.py" in get
  408.                 self.model._meta.object_name

During handling of the above exception (Playlist matching query does not exist.), another exception occurred:

File "C:\Users\hooriaishtiaq\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)

File "C:\Users\hooriaishtiaq\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\hooriaishtiaq\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\hooriaishtiaq\workspace\sound\core\views.py" in add_to_playlist
  129.         Playlist.add_music(new_song)

File "C:\Users\hooriaishtiaq\workspace\sound\core\models.py" in add_music
  70.         playlist, created = cls.objects.get_or_create(songs=new_song)

File "C:\Users\hooriaishtiaq\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\db\models\manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "C:\Users\hooriaishtiaq\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\db\models\query.py" in get_or_create
  541.             return self._create_object_from_params(kwargs, params)

File "C:\Users\hooriaishtiaq\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\db\models\query.py" in _create_object_from_params
  575.                 obj = self.create(**params)

File "C:\Users\hooriaishtiaq\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\db\models\query.py" in create
  420.         obj = self.model(**kwargs)

File "C:\Users\hooriaishtiaq\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\db\models\base.py" in __init__
  496.                             _setattr(self, prop, kwargs[prop])

File "C:\Users\hooriaishtiaq\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\db\models\fields\related_descriptors.py" in __set__
  538.             % self._get_set_deprecation_msg_params(),

Exception Type: TypeError at /add_to_playlist/add/11/
Exception Value: Direct assignment to the forward side of a many-to-many set is prohibited. Use songs.set() instead.

【问题讨论】:

  • 您的问题的标题与您提到的错误完全不同。您要解决的正确错误是什么?另外,请向我们展示您的错误的整个堆栈跟踪,目前尚不清楚错误发生在哪里。

标签: python django python-3.x get manytomanyfield


【解决方案1】:

这里缺少播放列表 ID:

 <a class="dropdown-item" href="{% url 'add_to_playlist' operation='add' pk=i.pk playlist_id=v.id%}">Add to{{v.name}}</a>

在这种情况下你可以这样做:

def add_to_playlist(request, operation, pk, playlist_id):
    playlist = Playlist.objects.get(pk=playlist_id)
    new_song = Music.objects.get(pk=pk)
    if operation == 'add':
        playlist.songs.add(new_song)
    elif operation == 'remove':
        playlist.songs.remove(new_song)
    return redirect('/')

【讨论】:

    【解决方案2】:

    我认为你的方法是错误的,因为当你调用remove_music时,你首先创建新歌,然后删除??,这不符合逻辑:

    @classmethod
        def remove_music(cls, new_song):
            playlist, created = cls.objects.get_or_create(songs=new_song)
            playlist.songs.remove(new_song)
    

    您应该在您的方法中添加 try 和 except,如下所示:

    @classmethod
        def remove_music(cls, new_song):
            try:        
                playlist = cls.objects.get(songs=new_song)
                playlist.songs.remove(new_song)
            except cls.DoesNotExist:
                print("Song couldn't removed") # or something
    

    【讨论】:

      猜你喜欢
      • 2021-07-01
      • 2018-10-05
      • 2020-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-18
      • 2019-03-02
      • 1970-01-01
      相关资源
      最近更新 更多