Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: 'QuerySet' object has no attribute 'pk': When I try to Bulk Update and Delete the Records #86

Open
shasan11 opened this issue Oct 18, 2024 · 1 comment

Comments

@shasan11
Copy link

models.py

import uuid
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone

class ToDoCategory(models.Model):
    """Model representing a category for ToDos (e.g. Work, Personal)."""
    id = models.BigAutoField(primary_key=True)  # Explicitly define id field
    uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
    name = models.CharField(max_length=100, unique=True)
    description = models.TextField(blank=True, null=True)
    active=models.BooleanField(default=True)

    class Meta:
        verbose_name = 'To-Do Category'
        verbose_name_plural = 'To-Do Categories'

    def __str__(self):
        return self.name


class ToDoTag(models.Model):
    """Model representing tags for ToDos (e.g. Urgent, Important)."""
    id = models.BigAutoField(primary_key=True)  # Explicitly define id field
    uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
    name = models.CharField(max_length=50, unique=True)
    color = models.CharField(max_length=7, default='#000000')  # Hex color code
    active=models.BooleanField(default=True)
    
    class Meta:
        verbose_name = 'To-Do Tag'
        verbose_name_plural = 'To-Do Tags'

    def __str__(self):
        return self.name


class ToDo(models.Model):
    """Model representing a ToDo item."""
    PRIORITY_CHOICES = [
        ('L', 'Low'),
        ('M', 'Medium'),
        ('H', 'High'),
        ('U', 'Urgent'),
    ]

    id = models.BigAutoField(primary_key=True)  # Explicitly define id field
    uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
    title = models.CharField(max_length=200)
    description = models.TextField(blank=True, null=True)
    due_date = models.DateTimeField(blank=True, null=True)
    created_at = models.DateTimeField(default=timezone.now)
    updated_at = models.DateTimeField(auto_now=True)
    completed = models.BooleanField(default=False)
    priority = models.CharField(max_length=1, choices=PRIORITY_CHOICES, default='M')
    category = models.ForeignKey(ToDoCategory, on_delete=models.SET_NULL, null=True, blank=True)
    tags = models.ManyToManyField(ToDoTag, blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    active=models.BooleanField(default=True)

    class Meta:
        verbose_name = 'To-Do'
        verbose_name_plural = 'To-Dos'
        ordering = ['due_date', 'priority', 'created_at']

    def __str__(self):
        return self.title

serializers.py

from rest_framework import serializers
from .models import ToDo, ToDoCategory, ToDoTag
from rest_framework_bulk import BulkListSerializer,BulkSerializerMixin
from rest_framework_bulk import (
    BulkListSerializer,
    BulkSerializerMixin,
    ListBulkCreateUpdateDestroyAPIView,
)

class ToDoCategorySerializer(serializers.ModelSerializer,BulkSerializerMixin):
    class Meta:
        

        model = ToDoCategory
        fields="__all__"
        list_serializer_class = BulkListSerializer

class ToDoTagSerializer(serializers.ModelSerializer,BulkSerializerMixin):
    class Meta:
        model = ToDoTag
        fields = ['id', 'uuid', 'name', 'color']
        update_lookup_field = 'id'
        list_serializer_class = BulkListSerializer

class ToDoSerializer(serializers.ModelSerializer,BulkSerializerMixin):
    category = ToDoCategorySerializer(read_only=True)
    tags = ToDoTagSerializer(many=True, read_only=True)

    class Meta:
        model = ToDo
        update_lookup_field = 'id'
        fields = ['id', 'uuid', 'title', 'description', 'due_date', 'created_at', 'updated_at', 'completed', 'priority', 'category', 'tags', 'user']
        list_serializer_class = BulkListSerializer

views.py

from rest_framework import viewsets
from .models import ToDo, ToDoCategory, ToDoTag
from .serializers import ToDoSerializer, ToDoCategorySerializer, ToDoTagSerializer
from rest_framework_bulk import (
    BulkListSerializer,
    BulkSerializerMixin,
    ListBulkCreateUpdateDestroyAPIView,
    BulkModelViewSet
)
from rest_framework.permissions import AllowAny  # Import AllowAny

class ToDoCategoryViewSet(BulkModelViewSet):
    model=ToDoCategory
    queryset = ToDoCategory.objects.all()
    serializer_class = ToDoCategorySerializer
     

class ToDoTagViewSet(BulkModelViewSet):
    queryset = ToDoTag.objects.all()
    serializer_class = ToDoTagSerializer
    update_lookup_field = 'id'

class ToDoViewSet(BulkModelViewSet):
    queryset = ToDo.objects.all()
    serializer_class = ToDoSerializer
    update_lookup_field = 'id'

urls.py

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ToDoCategoryViewSet, ToDoTagViewSet, ToDoViewSet
from rest_framework_bulk.routes import BulkRouter

router = BulkRouter()
router.register(r'todo-categories', ToDoCategoryViewSet)
router.register(r'todo-tags', ToDoTagViewSet)
router.register(r'todos', ToDoViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

@shasan11
Copy link
Author

Solved the issue , the model with any unique constraint forbids from Bulkmodelset bulk update, its better to write the bulk update logic on own

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant