Как работает обновление полей m2m? Django Rest Framework - PullRequest
1 голос
/ 20 октября 2019

У меня есть код, где Product модель имеет поле M2M Comment модель. В views.py я создал методы для получения Product на id и всех объектов Product, но есть проблема с его обновлением. Я не могу полностью понять, как обновить Product поле комментариев. Я уже перепробовал много разных ответов и идей, но ничто не помогает мне. Я использую PUT метод для обновления.

Мои основные вопросы:

  • Где и как цель Product id вчтобы обновить поле комментариев в нем?
  • После того, как я найду Product по id, как я могу обновить в нем комментарии полей M2M?

Я пытался:

Полностью потеряно: многие ко многим с сериализаторами и обновлением в Django Rest Framework

Не работает вообще, кричит о 'collections.OrderedDict' object has no attribute 'id'

Django Rest обновляет многие ко многим по id

Это делает PrimaryKeyRelatedField, что мне не подходит.

Как обновить многие на многие Django REST?

Недостаточно информации в ответе, застрял на ней.

I read , но не нашел полезной информации омоя проблема

products / models.py


from django.db import models

from comments.models import Comment


# Create your models here.


class Product(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=150, blank=True)
    description = models.TextField(default="No description")
    category = models.CharField(max_length=255, blank=True)
    price = models.DecimalField(default=100, max_digits=15, decimal_places=2, blank=True)
    photo_one = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, null=True)
    photo_two = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, null=True)
    photo_three = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, null=True)
    photo_four = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, null=True)
    is_popular = models.BooleanField(default=False)
    is_hit = models.BooleanField(default=False)
    has_sale = models.IntegerField(default=0)
    comments = models.ManyToManyField(Comment, blank=True)

    def __str__(self):
        return self.name

comments / models.py

import uuid

from django.db import models


# Create your models here.
class Comment(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    username = models.CharField(max_length=255, default="default")
    text = models.TextField()
    rating = models.IntegerField()

    def __string__(self):
        return self.username

products / serializers.py

class ProductSerializer(serializers.ModelSerializer):
    comments = CommentSerializer(many=True)

    class Meta:
        model = Product
        fields = '__all__'

    def update(self, instance, validated_data):
        submitted_comments = validated_data.get('comments')
        if submitted_comments:
            for comment in submitted_comments:
                comment_instance = Comment.objects.get(id=comment.id)
                instance.children.add(comment_instance)
        instance.save()
        return instance

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ('id', 'username', 'text', 'rating')

products / views.py

import django_filters
from rest_framework import status
from rest_framework.generics import ListAPIView, RetrieveUpdateAPIView
from rest_framework.response import Response

from .models import Product
from .pagination import CustomPagination
from .serializers import ProductSerializer


class GetProductById(RetrieveUpdateAPIView):
    serializer_class = ProductSerializer
    filter_class = ProductFilter
    queryset = Product.objects.all()

    def get_product(self, pk):
        try:
            product = Product.objects.get(pk=pk)
        except Product.DoesNotExist:
            content = {
                'status': 'Not Found'
            }
            return Response(content, status=status.HTTP_404_NOT_FOUND)
        return product

    def get(self, request, pk):
        product = self.get_product(pk)
        serializer = ProductSerializer(product)
        return Response(serializer.data, status=status.HTTP_200_OK)

class ProductFilter(django_filters.FilterSet):
    product_id = django_filters.UUIDFilter(name='id')

    class Meta:
        model = Product
        fields = ['id']


class GetProducts(ListAPIView):
    serializer_class = ProductSerializer
    pagination_class = CustomPagination

    def get_queryset(self):
        products = Product.objects.all()
        return products

    def get(self, request):
        products = self.get_queryset()
        paginate_queryset = self.paginate_queryset(products)
        serializer = self.serializer_class(paginate_queryset, many=True)
        return self.get_paginated_response(serializer.data)

* products / urls.py

from django.urls import path

from . import views

urlpatterns = [
    path('api/products/', views.GetProducts.as_view(), name='get_products'),
    path('api/product/<pk>/', views.GetProductById.as_view(), name='get_put_product')
]

Ожидаю успешную цель на Product id и нахожу поле product.comments

Я ожидаю успешного добавления нового Comment к Product в поле комментариев

...