Reputation: 5674
I'm working on a project with Python(3.6) and Django(2.0) in which I need to make a field in child model required on the base of a condition for a field in parent model class.
If the service is multiple then the routing and configuration fields will be required otherwise it's not necessary to be filled.
Here's my code from models.py
From models.py:
services = (
('Single', 'Single'),
('Multiple', 'Multiple'),
)
class DeploymentOnUserModel(models.Model):
deployment_name = models.CharField(max_length=256, )
credentials = models.TextField(blank=False)
project_name = models.CharField(max_length=150, blank=False)
project_id = models.CharField(max_length=150, blank=True)
cluster_name = models.CharField(max_length=256, blank=False)
zone_region = models.CharField(max_length=150, blank=False)
services = models.CharField(max_length=150, choices=services)
configuration = models.TextField(blank=True)
routing = models.TextField(blank=True)
def save(self, **kwargs):
if self.services == 'Multiple' and not self.routing and not self.configuration:
raise ValidationError("You must have to provide routing for multiple services deployment.")
super().save(**kwargs)
From serializers.py:
class DeploymentOnUserSerializer(serializers.ModelSerializer):
class Meta:
model = DeploymentOnUserModel
fields = '__all__'
From apiview.py:
class DeploymentsList(generics.ListCreateAPIView):
queryset = DeploymentOnUserModel.objects.all()
serializer_class = DeploymentOnUserSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
serializer = DeploymentOnUserSerializer(data=self.request.data)
validation = serializer.is_valid()
if validation is True:
perform_deployment(self.request.data)
self.create(request=self.request)
else:
return Response('You haven\' passed the correct data ')
return Response(serializer.data)
Post payload:
{
"deployment_name": "first_deployment",
"credentials":{
"type": "service_account",
"project_id": "project_id",
"private_key_id": "private_key_id",
"private_key": "-----BEGIN PRIVATE KEY",
"client_email": "client_email",
"client_id": "client_id",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "client_x509_cert_url"
},
"project_name": "project_name",
"project_id": "project_id",
"cluster_name": "numpy",
"zone_region": "europe-west1-d",
"services": "Single",
"configuration": "",
"routing": ""
}
Update: Now I have implemented apiview and serializers for these models. When I submit a post request with the
services=Single
without the values forconfiguration & routing
it returnsYou haven't passed the correct data.
This means the save method, is not working. Help me, please!
Thanks in advance!
Upvotes: 3
Views: 3991
Reputation: 88629
apart from my comment, you could override the save()
method of AwdModel
model.
from django.core.exceptions import ValidationError
class AwdModel(UserAccountModel):
source_zip = models.FileField(upload_to='media/awdSource/', name='awd_source')
routing = models.TextField(name='routing', null=True)
def save(self, **kwargs):
if not self.id and self.services == 'Multiple' and not self.routing:
raise ValidationError("error message")
super().save(**kwargs)
self.id
will be null
or similar if it's a new instance,hence the validation checks happens only if instance is created
Update-1 use this payload to POST
{
"deployment_name": "first_deployment",
"credentials":{"test_key":"test_value"},
"project_name": "project_name",
"project_id": "project_id",
"cluster_name": "numpy",
"zone_region": "europe-west1-d",
"services": "Single",
"configuration": "",
"routing": ""
}
update-2
try this for your serializer,
class DeploymentOnUserSerializer(serializers.ModelSerializer):
credentials = serializers.JSONField()
class Meta:
model = DeploymentOnUserModel
fields = '__all__'
Upvotes: 2