Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何约束和验证Django m2m和外键字段_Python_Django - Fatal编程技术网

Python 如何约束和验证Django m2m和外键字段

Python 如何约束和验证Django m2m和外键字段,python,django,Python,Django,我有这些模型: class Client(models.Model): name = models.CharField(_('name'), max_length=255) info = models.OneToOneField('ClientInfo', verbose_name=_('info'), related_name='client',

我有这些模型:

class Client(models.Model):
    name = models.CharField(_('name'), max_length=255)

    info = models.OneToOneField('ClientInfo',
                                verbose_name=_('info'),
                                related_name='client',
                                on_delete=models.PROTECT)

    is_active = models.BooleanField(_('is active'), default=False) 

class ClientInfo(models.Model):
    address = models.CharField(_('name'), max_length=255)
    
    other fields...

class Result(models.Model):
    RESULT_CHOICES = (('N', _('Notified')),
                     ('NL', _('No located')))

    created_by= models.ForeignKey(OfficeEmployee,
                                 verbose_name=_('created by'),
                                 on_delete=models.PROTECT)

    result_type = models.CharField(_('result type'),
                                   max_length=2,
                                   default='N',
                                   choices=RESULT_CHOICES)

    other fields...

class Visit(models.Model):
    client = models.ForeignKey(Client,
                                  verbose_name=_('client'),
                                  related_name='visit',
                                  on_delete=models.PROTECT)

    results = models.ManyToManyField(Result,
                                     verbose_name=_('results'),
                                     related_name='visit',
                                     blank=True)    

    other fields...
我想添加某些限制,但我对这些模型有困难,因为我几乎看不到需要向相关字段添加限制:

  • 如果“客户机”尚未与其建立关系,如何避免出现“ClientInfo”条目
  • 如果与之相关的客户端被标记为未激活,如何防止将“NL”类型的“结果”条目添加到现有的“访问”中
  • 我曾考虑使用django内置信号,但我不知道是否可以通过重写某些验证方法或使用Meta类在类本身中定义所需的限制。最后一个原因是我对信号的使用在性能上是否非常昂贵感到震惊

  • 我发现最好的方法是改变m2m_:

    @receiver(m2m_changed, sender=results_through, dispatch_uid='check_employeer_status')
    def check_employeer_status(sender, **kwargs):
        instance = kwargs.get('instance')
        action = kwargs.get('action')
        model = kwargs.get('model')
    
        if action == 'pre_add':
            if model and model.result_type != 'NL':
                if instance and not instance.employeer.is_active:
                    raise ValidationError(('employeer '
                                           'is not active. Only no located results are allowed'))
    

    信号只是Pythic回调,我不认为这些开销比其他Python代码贵。与信号的使用相比,应用程序中可能存在许多更大的性能瓶颈。尽管如此,这些听起来像是非常标准的验证,您可以从序列化程序(如果使用DRF)或模型中的
    clean
    进行验证。如果你有特定问题,你应该先戳他们一下,然后编辑你的帖子。当调用
    访问.results.add
    我如何检查
    def clean(self):…
    或其他验证方法给定结果实例的属性?