Пытаюсь решить ошибку "Прямое присвоение прямой стороне множества "многие-ко-многим" запрещено. Вместо этого используйте category.set()." ошибка

Я студент, работающий над проектом для моего буткемпа по кодированию, и мне нужно решить проблему с полем "многие ко многим". Тема проекта - приложение, которое позволяет пользователям размещать скриншоты из различных видеоигр и маркировать их на основе категории, сторонних инструментов редактирования и захвата.

Я пытаюсь написать код для POST и PUT запросов, который позволит пользователю выбрать несколько объектов в форме React.js.

Я бы также попробовал протестировать любое решение в postman. Я добавил фикстуры в свою базу данных, и фикстуры работают, но при попытке протестировать с помощью необработанного JSON в теле, как это:

`

         "category": 1,

or

 "category": [
            1,
            2,
            3
        ]

` Я получаю ошибку, показанную в заголовке этого сообщения.

Я использую Python 3.9.10 и Django 4.14.

Моя модель выглядит следующим образом:

screenshot.py `

from django.db import models
from .archer import Archer
from .editingtool import EditingTool
from .capturetool import CaptureTool
from .category import Category

class Screenshot(models.Model):
    archer = models.ForeignKey (Archer, on_delete=models.CASCADE)
    image = models.CharField(max_length=255, null=True)
    content = models.TextField()
    captureTool = models.ForeignKey (CaptureTool, on_delete=models.CASCADE)
    editingTool = models.ForeignKey (EditingTool, on_delete=models.CASCADE)
    category = models.ManyToManyField ('Category', through='ScreenshotCategory')
    timestamp = models.DateField(auto_now_add=True)

`

category.py `

from django.db import models

class Category(models.Model):
    description = models.CharField(max_length=255)

**screenshotcategory.py **

from django.db import models
from .screenshot import Screenshot

class ScreenshotCategory(models.Model):
    screenshot = models.ForeignKey (Screenshot, on_delete=models.CASCADE)
    category = models.ForeignKey ('Category', on_delete=models.CASCADE, related_name="screenshot_category")

`

и мой вид выглядит следующим образом

screenshot.py `

def create(self, request):
        """ Handle a POST request for a Screenshot item """
        
        archer  = Archer.objects.get(user=request.auth.user)
        captureTool = CaptureTool.objects.get(pk=request.data["captureTool"])
        editingTool = EditingTool.objects.get(pk=request.data["editingTool"])
        category = Category.objects.get(pk=request.data["category"])
        
        new_screenshot = Screenshot.objects.create(
            archer=archer,
            image=request.data["image"],
            content=request.data["content"],
            captureTool=captureTool,
            editingTool=editingTool,
            category = category,
            timestamp=request.data["timestamp"]
            )
        serializer = ScreenshotSerializer(new_screenshot)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def update(self, request, pk):
        """ Handles a PUT request for a Screenshot item """
        
        captureTool = CaptureTool.objects.get(pk=request.data["captureTool"])
        editingTool = EditingTool.objects.get(pk=request.data["editingTool"])
        category = Category.objects.get(pk=request.data["category"])

        editing_screenshot = Screenshot.objects.get(pk=pk)
        editing_screenshot.image = request.data["image"]
        editing_screenshot.content = request.data["content"]
        editing_screenshot.captureTool = captureTool
        editing_screenshot.editingTool = editingTool
        editing_screenshot.category =category
        editing_screenshot.save()

        return Response(None, status=status.HTTP_204_NO_CONTENT)

`

Я пробовал добавить, используя код, как он, но безуспешно. Я ожидал, что при тестировании в post man я получу обратно объект, который выглядит следующим образом

`

"id": 6,
        "archer": 1,
        "image": "https://url.png",
        "content": "content",
        "captureTool": 1,
        "editingTool": 1,
        "category": [
            1,
            2,
            3
        ],
        "timestamp": "2020-03-12"

` но вместо этого я получаю ошибку.

Я думаю, что ваше решение будет примерно таким:

screen_shot = ScreenshotCategory.objects.get(id=pk)
Category = Category.objects.get(id = orden_id)
screen_shot.category.add(category)

надеюсь, это поможет

Вам необходимо установить все объекты модели Category в модели Screenshot, которые содержат поле "многие ко многим" модели Category

В основном поле many-to-many имеет список объектов, а не один объект, поэтому вам нужно добавить все объекты в поле many-to-many. например, так

здесь я поместил код для метода create.

def create(self, request):
        """ Handle a POST request for a Screenshot item """
        
        archer  = Archer.objects.get(user=request.auth.user)
        captureTool = CaptureTool.objects.get(pk=request.data["captureTool"])
        editingTool = EditingTool.objects.get(pk=request.data["editingTool"])
        
        new_screenshot = Screenshot.objects.create(
            archer=archer,
            image=request.data["image"],
            content=request.data["content"],
            captureTool=captureTool,
            editingTool=editingTool,
            timestamp=request.data["timestamp"]
        ).save()

        for i in request.data["category"]:
            cate = Category.objects.get(id=i)
            new_screenshot.category.add(cate)

        serializer = ScreenshotSerializer(new_screenshot)
        return Response(serializer.data, status=status.HTTP_201_CREATED)
Вернуться на верх