0
votes

I need multiple values to be in the courses' contacts, for example phone, facebook etc.

I'm overriding create method to make writable nested fields. Everything works fine with "branches". I'm confused because I can't get why Contact is not iterable.

Models.py:

class Branch(models.Model):
    latitude = models.CharField(max_length=50)
    longitude = models.CharField(max_length=50)
    address = models.CharField(max_length=100)

    class Meta:
        ordering = ['latitude']

    def __str__(self):
        return self.address

class Contact(models.Model):
    type = models.IntegerField(choices=TYPE, default=1)
    value = models.CharField(max_length=100, null=False)

    class Meta:
        ordering = ['type']

    def __str__(self):
        return "{} {}".format(self.type, self.value)

class Course(models.Model):
    ...
    branches = models.ForeignKey(Branch, on_delete=models.CASCADE, null=False, default=True)
    contacts = models.ForeignKey(Contact, on_delete=models.CASCADE, null=False, default=True)

    class Meta:
        ordering = ['name']

    def __str__(self):
        return self.name

Serializers.py:

class CourseSerializer(serializers.ModelSerializer):
    ...
    branches = BranchSerializer(many=True)
    contacts = ContactSerializer(many=True)

    class Meta:
        model = Course
        fields = ['name', 'description', 'category', 'logo', 'contacts', 'branches']

    def create(self, validated_data):
        branches_data = validated_data.pop('branches')
        contacts_data = validated_data.pop('contacts')
        course = Course.objects.create(**validated_data)
        for branches in branches_data:
            branch = Branch.objects.create(**branches)
            course.branches = branch
        for contacts in contacts_data:
            contact = Contact.objects.create(**contacts)
            course.contacts = contact
        return course

UPD: Traceback:

File "/courseapp_task/venv/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner 34. response = get_response(request)

File "/courseapp_task/venv/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 115. response = self.process_exception_by_middleware(e, request)

File "/courseapp_task/venv/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 113. response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/courseapp_task/venv/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view 54. return view_func(*args, **kwargs)

File "/courseapp_task/venv/lib/python3.6/site-packages/rest_framework/viewsets.py" in view 114. return self.dispatch(request, *args, **kwargs)

File "/courseapp_task/venv/lib/python3.6/site-packages/rest_framework/views.py" in dispatch 505. response = self.handle_exception(exc)

File "/courseapp_task/venv/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception 465. self.raise_uncaught_exception(exc)

File "/courseapp_task/venv/lib/python3.6/site-packages/rest_framework/views.py" in raise_uncaught_exception 476. raise exc

File "/courseapp_task/venv/lib/python3.6/site-packages/rest_framework/views.py" in dispatch 502. response = handler(request, *args, **kwargs)

File "/courseapp_task/venv/lib/python3.6/site-packages/rest_framework/mixins.py" in create 20. headers = self.get_success_headers(serializer.data)

File "/courseapp_task/venv/lib/python3.6/site-packages/rest_framework/serializers.py" in data 559. ret = super().data

File "/courseapp_task/venv/lib/python3.6/site-packages/rest_framework/serializers.py" in data 261. self._data = self.to_representation(self.instance)

File "/courseapp_task/venv/lib/python3.6/site-packages/rest_framework/serializers.py" in to_representation 526. ret[field.field_name] = field.to_representation(attribute)

File "/courseapp_task/venv/lib/python3.6/site-packages/rest_framework/serializers.py" in to_representation 675. self.child.to_representation(item) for item in iterable

1
Please show the full traceback. - Daniel Roseman

1 Answers

1
votes

The problem is not in your nested serializers. The problem is in your models themselves.

A ForeignKey is a many to one relationship. The way you have defined things, a Course can only have one branch and one contact. Calling the fields "branches" and "contacts" doesn't change that, and neither does setting "many=True" in the serializers.

You need to change the models so that the ForeignKeys are on Branch and Contact themselves, pointing at Course. The serializer would then use the related names.

Note, you shouldn't need to define create; everything there should just work.