Search code examples
djangodjango-modelsdjango-rest-frameworkserialization

How to fix 'AttributeError: 'Person' object has no attribute '_default_manager' in Django is_valid() method


I'm using django rest and I'm trying to update my django model with the changed values from a form POST.I place the model to be updated and new data in the serializer instance.

model_serializer = serializer.PersonSerializer(queryset, request.POST)

When performing model_serializer.is_valid() I get the error AttributeError: 'Person' object has no attribute '_default_manager'

I've looked at similar questions to this. I haven't found anything regarding a model object not having a '_default_manager'

In these questions they suggest changing the name of method/model due to conflicts. This hasn't worked for me.

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Person()
        fields = '__all__'
url(r'^api/personview/', views.PersonView.as_view()),
class PersonView(APIView):
    renderer_classes = [TemplateHTMLRenderer]
    template_name = 'rest_person_form.html'

    def get(self, request):
        queryset = models.Person.objects.all().last()
        model_serializer = serializer.PersonSerializer(queryset)
        return Response({'serializer': model_serializer, 'queryset': queryset})


    def post(self, request):
        queryset = models.Person.objects.all().last()
        model_serializer = serializer.PersonSerializer(queryset, request.POST)
        model_serializer.is_valid()
        model_serializer.save()
        return Response({'serializer':model_serializer})

I'm expecting the is_valid() method to pass without errors to allow me to save my updated details into my model.


Solution

  • Attribute model is waiting for a class, not an instance.

    class PersonSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Person # No () at the end
            fields = '__all__'
    

    Tip: If you aren't using the return from is_valid(), you could use is_valid(raise_exception=True) to raise error 400 automatically.