I am a student working on a project for my coding bootcamp and I'm having to resolve an issue with a many to many field. The theme of the project is app that lets users post screenshots from various video game and label them bases on category, 3rd party editing and capture tools.
I'm trying to write code for POST and PUT requests that will allow a user to select several objects in a React.js form.
I'd also try and test whatever solution I get in postman. I've added fixtures into my database and the fixtures work, but when attempting to test by using raw JSON in the body like this:
`
"category": 1,
or
"category": [
1,
2,
3
]
` I get the error show in the title of this post.
I'm using Python 3.9.10 and Django 4.14.
my model looks like this:
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")
`
and my view looks like this
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)
`
I've tried adding using the code as it to no success. I was expecting that when testing in post man to get back an object that looks like this
`
"id": 6,
"archer": 1,
"image": "https://url.png",
"content": "content",
"captureTool": 1,
"editingTool": 1,
"category": [
1,
2,
3
],
"timestamp": "2020-03-12"
` but instead i get an error.
CodePudding user response:
I think your solution will be something like this:
screen_shot = ScreenshotCategory.objects.get(id=pk)
Category = Category.objects.get(id = orden_id)
screen_shot.category.add(category)
hope it helps
CodePudding user response:
You need to set all objects of Category
model in Screenshot
model which contain many-to-many field of Category
model
basically many-to-many field have list of object, not single object so, you need to add all objects in many-to-many field. like this
here i put code for create
method.
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)