Skip to main content
 首页 » 编程设计

python之根据 Django 模型中的条件根据需要创建模型字段

2024年09月07日26fff_TT

我正在使用 Python(3.6) 和 Django(2.0) 开发一个项目,我需要在子模型中创建一个字段父模型类中字段的条件。

如果service是多个那么routing和configuration字段将是必需的,否则不需要填写。

这是我来自 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 for configuration & routing it returns You haven't passed the correct data.

这意味着保存方法不起作用。 请帮助我!

提前致谢!

请您参考如下方法:

除了我的评论之外,您还可以覆盖 AwdModel 模型的 save() 方法。

 
<b>from django.core.exceptions import ValidationError</b> 
 
 
class AwdModel(UserAccountModel): 
    source_zip = models.FileField(upload_to='media/awdSource/', name='awd_source') 
    routing = models.TextField(name='routing'<b>, null=True</b>) 
 
    <b>def save(self, **kwargs): 
        if not self.id and self.services == 'Multiple' and not self.routing: 
            raise ValidationError("error message") 
        super().save(**kwargs)</b> 
 

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": "" 
} 

更新-2 为你的序列化程序试试这个,

class DeploymentOnUserSerializer(serializers.ModelSerializer): 
    <b>credentials = serializers.JSONField()</b> 
    class Meta: 
        model = DeploymentOnUserModel 
        fields = '__all__'