0

Using django-rest framework 3.3.3

I am trying to update existing data in my database using the django-rest framework, following a previously posted solution :django-rest-framework 3.0 create or update in nested serializer

I'm fairly new to django in general, and the rest framework.

Given the following models:

class Clinic(models.Model):

    name = models.TextField()
    streetNumber = models.IntegerField()
    unitNumber = models.CharField(max_length=10, blank=True, null=True)
    streetName = models.CharField(max_length=50)
    city = models.CharField(max_length=50)
    province = models.CharField(max_length=3)
    country = models.CharField(max_length=30)
    postalCode = models.CharField(max_length=6)
    phone = models.CharField(max_length=10)

    def __str__(self):
        return self.name


class Time (models.Model):

     clinic = models.ForeignKey(Clinic, related_name='times')
     appointmentTime = models.CharField(max_length=100)

     def __str__(self):
         return self.appointmentTime

And the following serializers:

class TimeSerializer(serializers.ModelSerializer):

    class Meta:
        model = Time
        fields = ('appointmentTime',)


class ClinicSerializer(serializers.ModelSerializer):

    times = TimeSerializer(many=True)

    class Meta:
        model = Clinic
        fields = '__all__'

    def update(self, instance, validated_data):

        instance.name = validated_data['name']
        instance.streetName = validated_data['streetName']
        instance.unitNumber = validated_data['unitNumber']
        instance.city = validated_data['city']
        instance.province = validated_data['province']
        instance.country = validated_data['country']
        instance.postalCode = validated_data['postalCode']
        instance.phone = validated_data['phone']
        #print(instance)
        instance.save()

        times_data = [item['id'] for item in validated_data['times']]
        print(times_data)
        for time in instance.clinics:
            if time.id not in times_data:
                time.delete()

        for item in validated_data['times']:
            time = Time(id=item['id'], clinic=instance,
            appointmentTime=item['appointmentTime'])
            time.save()

        return instance

And the following view:

class ClinicList(APIView):

def get(self,request):
    clinics = Clinic.objects.all()
    serializer = ClinicSerializer(clinics, many=True)
    return Response({'results': serializer.data})

def post(self, request):

    serializer = ClinicSerializer(data=request.data)
    if serializer.is_valid():

        serializer.update(Clinic, serializer.data)

        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

And the following existing data:

{
        "id": 2,
        "times": [
            {
                "appointmentTime": "time3"
            },
            {
                "appointmentTime": "time3"
            }
        ],
        "name": "Example Clinic",
        "streetNumber": 123,
        "unitNumber": "",
        "streetName": "Example Street",
        "city": "Exampletown",
        "province": "Ont",
        "country": "Canada",
        "postalCode": "A1A1A1",
        "phone": "9059059059"
    }

With my JSON POST data being:

{
        "id": 2,
        "times": [
            {
                "appointmentTime": "AAAA"
            },
            {
                "appointmentTime": "time3"
            }
        ],
        "name": "Example Clinic",
        "streetNumber": 123,
        "unitNumber": "",
        "streetName": "Example Street",
        "city": "Exampletown",
        "province": "Ont",
        "country": "Canada",
        "postalCode": "A1A1A1",
        "phone": "9059059059"
    }

My problem is that I am receiving an error stating:

File"C:\Users\colin\Documents\GitHub\Walk_inExpressAPI\clinics\serializer.py",

line 31, in update

instance.save()

TypeError: save() missing 1 required positional argument: 'self'

I'm not sure what Im doing wrong here, or what value to supply to instance.save() to correct this error. I've checked that instance was an object of type Clinic.

What i'm trying to accomplish is that each Clinic can have multiple appointment times. They wont share appointmentTime objects, because I would like to be able to delete an appointentTime each time a new appointment is booked, and each clinic will require its own set of available appointmentTimes.

Hopefully you guys can help lead me in the right direction! Thanks!

Community
  • 1
  • 1

1 Answers1

0

You should user the method PUT in your APIView:

def put(self, request, pk):
   clinics = Clinic.objects.get(pk=pk)
   serializer = ClinicSerializer(clinics, data=request.data)
   if serializer.is_valid():
       serializer.save()
       return Response(serializer.data)
   return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

so in you url.py should have a pk, to identify the object you want to modify:

urlpatterns = [
    url(r'^snippets/$', views.ClinicList.as_view()),
    url(r'^snippets/(?P<pk>[0-9]+)/$', views.ClinicList.as_view()),
]

In update method change the instance attributes like:

instance.name = validated_data.get('name',instance.name)

Try to see the example in DRF page as well.

Matheus Veleci
  • 344
  • 2
  • 7