Django模型/表单清理,验证和独特

时间:2015-07-26 17:20:47

标签: django validation django-rest-framework

我正在尝试使用具有以下清除和验证特征的“name”和“client”字段创建Model和ModelForm。我可以管理每个人的要求,但似乎无法让他们一起工作。

  • 经过身份验证的用户可以输入项目的名称
  • 项目以名称保存并强制使用与用户帐户关联的客户端。
  • 通过''.join(name.strip()。split())
  • 清理名称
  • 验证名称,以便(cleaning_name.lower(),client)是唯一的
    • EG:如果用户的关联客户端中存在“FOO BAR”,则用户输入“foo bar”时会收到错误

这是一个相当简单的模型:

class Item(BaseModel):
    class Meta:
        unique_together = (("client", "name"),)

    client = models.ForeignKey(Client,related_name='items',null=True,blank=False)
    name = models.CharField(max_length=64, null=False, blank=False)

    def clean_name(self):
        return  ' '.join(self.cleaned_data['name'].strip().split())

所有项目创建/更新都通过Django REST Framework完成:

class ItemSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Item
        fields = ('id','name')

    def create(self,validated_data):
        item = Item.objects.create(name=validated_data['name'],client=self.context['request'].user.client)
        item.save()
        return item

我更喜欢尽可能多的模型中的逻辑(例如,不使用SQL来创建索引),但如果需要,可以将一些验证推送到序列化器。

的Tx。

1 个答案:

答案 0 :(得分:0)

我最终得到了以下内容。唯一需要注意的是,我必须包含一个name_slug字段来存储以便进行排序。

models.py

class Item(BaseModel):
    class Meta:
        db_table = 'item'
        ordering = ['name_slug']

    # relations
    client = models.ForeignKey(Client,related_name='items',null=True,blank=False)

    # attributes
    name = models.CharField(max_length=64, null=False, blank=False)
    name_slug = models.CharField(max_length=64, null=False, blank=True)

    def clean(self):
        self.name = ' '.join(self.name.strip().split())
        if Item.objects.filter(client=self.client,name__iexact=self.name).count() > 0:
            raise ValidationError({'name': 'Name already exists. Please enter a different name'})

    def save(self, *args, **kwargs):
        self.name_slug = '-'.join(self.name.split()).lower()
        super(Item, self).save(*args, **kwargs) 

serializers.py

class ItemSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Item
        fields = ('id','name','name_slug')
        read_only_fields = ('name_slug',)

    def validate(self, attrs):
        attrs['client'] = self.context['request'].user.client
        instance = Item(**attrs)
        instance.clean()
        return { k: getattr(instance,k) for k in attrs.keys()}