How to validate different data in the same serializer in DRF

65 views
Skip to first unread message

Syed Shamikh Shabbir

unread,
Feb 23, 2021, 6:25:29 AM2/23/21
to Django REST framework
Hi,
I need help with something

This is my current setup
I want to be able to create new contributor entities as well as relating the old entities using the same data all when sending the parent Campaign data.
I cannot use create method in serializers as I want all my logic to be reusable since I'll have multiple different ways of creating the same thing


models.py

```python
   class BaseModel(models.Model):
        created_at = models.DateTimeField(
            editable=False, auto_now_add=True, verbose_name=_("Created At")
        )
        updated_at = models.DateTimeField(
            editable=False, auto_now=True, verbose_name=_("Updated At")
        )

        class Meta:
            abstract = True

    class Contributor(BaseModel):
        name = models.CharField(max_length=128)

    class Contact(BaseModel):
        name = models.CharField(max_length=128)
        phone_number = models.CharField(max_length=128, blank=True, null=True)

    class CampaignContributor(models.Model):
        campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE)
        contributor = models.ForeignKey(Contributor, on_delete=models.CASCADE)

        tags = ArrayField(
            models.CharField(max_length=255, blank=True, null=True), null=True
        )

    class Campaign(BaseModel):
        title = models.CharField(max_length=128)
        contributors = models.ManyToManyField(Contributor, through="CampaignContributor")


```


serializers.py

```python
    class ContactSerializer(serializers.ModelSerializer):
        class Meta:
            model = Contact
            fields = "__all__"
            depth = 1

    class ContributorSerializer(serializers.ModelSerializer):
        contacts = ContactSerializer(many=True)

        class Meta:
            model = Contributor
            fields = "__all__"
            depth = 1

    class CampaignContributorSerializer(serializers.ModelSerializer):
        contributor = ContributorSerializer()

        class Meta:
            model = CampaignContributor
            fields = "__all__"

    class CampaignSerializer(serializers.ModelSerializer)
        contributors = CampaignContributorSerializer(
            many=True, extra_excludes=["campaign"], source="campaigncontributor_set"
        )

        class Meta:
            model = Campaign
            fields = "__all__"
            depth = 1

```

views.py

```python
    class CampaignViewSet(viewsets.ModelViewSet):
        lookup_url_kwarg = "id"
        queryset = Campaign.objects.all()
        serializer_class = CampaignSerializer

        def create(self, request, *args, **kwargs):
            serializer = CampaignSerializer(request.data)
            serializer.is_valid(raise_exception=True)
            campaign = create_campaign(serializer.data)
            return Response(campaign)

```

services.py

```python

def create_campaign(validated_data):
    # handle model creation here
    return campaign

```

sample data I want to send

```json
{
  "title": "Test Campaign for SpringField",
  "contributors": [
    {"contributor": {"id": 1}}, // old contributor I want to be related to the newly created Campaign object
    {
      "contributor": {
        "name": "Homer Simpson",
        "contacts": [
          {
            "name": "Ned Flanders",
            "phoneNumber": "+123456789012"
          }
        ]
      },
      "tags": [
        "loopback",
        "regulator"
      ]
    }
  ]
}
```

What is the best way of doing this?
Reply all
Reply to author
Forward
0 new messages