【问题标题】:How to Remove validation from left table data in django如何从 django 中的左表数据中删除验证
【发布时间】:2017-07-05 21:03:18
【问题描述】:

2nd Screenshot of APIAPI Sample Screenshot

我是 Django 的新手,我想帮助关于屏幕截图中的验证,除了经过适当验证的用户信息之外,还有 company_name、location、title 和 user_location 字段 但我想从 company_name、location、title 和 user_location 字段中删除验证怎么办?

请找到上面的api截图和

请找到以下脚本,

views.py

class UserRegistrationView(generics.CreateAPIView):
    """
    Register a new user.
    """
    queryset = User.objects.all()
    permission_classes = (permissions.AllowAny, )

    def get_serializer_class(self, user_type=None):
        if user_type == 'student':
            return StudentRegistrationSerializer
        return ProfessionalRegistrationSerializer

    def post(self, request, user_type=None, format=None):
        serializer_class = self.get_serializer_class(user_type)
        serializer = serializer_class(data=request.data, context={'request': request})

        if serializer.is_valid(raise_exception=True)

            user = serializer.save(work_status=user_type)
            token, created = Token.objects.get_or_create(user=user)
            data = BasicUserSerializer(user, context={'request': request}).data
            data.update({"token": token.key})
            return Response(data)

serializes.py

class ProfessionalRegistrationSerializer(serializers.HyperlinkedModelSerializer):

    password = serializers.CharField(max_length=20, write_only=True)
    experiences = ExperienceSerializer(required=False)
    email = serializers.EmailField()
    first_name = serializers.CharField(max_length=30)
    last_name = serializers.CharField(max_length=30)

    class Meta:
        model = User
        fields = ('url', 'id', 'first_name', 'last_name', 'email', 'password',
        'experiences', 'headline')

    def validate_email(self, value):
        from validate_email_address import validate_email
        if User.all_objects.filter(email=value.lower()).exists():
            raise serializers.ValidationError('User with this email already exists.')
        # if not validate_email(value.lower(), check_mx=True):
        #     raise serializers.ValidationError('It looks like you may have entered an incorrect email address.')
        return value.lower()

    def create(self, validated_data):
        experiences = validated_data.pop('experiences')
        password = validated_data.pop('password')
        email = validated_data.pop('email')
        user = User.objects.create(
            username=email.lower(),
            email=email.lower(),
            role_id=1)
        user.set_password(password)
        user.save()
        user_location = experiences.pop('user_location')
        if hasattr(user, 'location'):
            user.location.location = user_location
            user.save()
        else:
            UserLocation.objects.create(user=user, location=user_location)
            Experience.objects.create(user=user)
        return user 

另一个用于体验的 serializes.py

class ExperienceSerializer(serializers.HyperlinkedModelSerializer):

    user_location = LocationField()
    location = LocationField()

    class Meta:
        model = Experience
        fields = ('id', 'company_name', 'company', 'description', 'location',
        'title', 'start_date', 'end_date', 'is_current', 'user_location')

我想从 company_name、company、description、location、title、start_date、end_date、user_location 中删除验证

实际上这些字段是第二页,意思是完成第一步后,用户会进入第二步,所以第二步字段是可选的

class ExperienceSerializer(serializers.HyperlinkedModelSerializer):

    user_location = LocationField()
    location = LocationField()

    class Meta:
        model = Experience
        fields = ('id', 'company_name', 'company', 'description', 'location',
            'title', 'start_date', 'end_date', 'is_current', 'user_location')

        def create(self, validated_data):

            return Experience.objects.create(field_a='value', field_b='value')

在上面的类中,应该怎么做才能去掉对

的验证
"error_msg": {
        "location": [
            "Expected a dictionary of items but got type \"str\"."
        ],
        "start_date": [
            "Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]]."
        ],
        "end_date": [
            "Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]]."
        ],
        "user_location": [
            "Expected a dictionary of items but got type \"str\"."
        ]
    } 

体验模型

class Experience(models.Model):

    """
    """

    user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='experiences')
    company_name = models.CharField(max_length=200, db_index=True, blank=True)
    company = models.ForeignKey('organisations.Organisation', null=True, blank=True, on_delete=models.SET_NULL)
    description = models.TextField(null=True, blank=True)
    location = models.ForeignKey('regions.Location', null=True, blank=True, on_delete=models.SET_NULL)
    start_date = models.DateField(null=True, blank=True)
    end_date = models.DateField(null=True, blank=True)
    title = models.CharField(max_length=200, db_index=True, blank=True)
    is_current = models.BooleanField(default=False)
    is_associated = models.BooleanField(default=False)
    created_at = models.DateTimeField(_('created at'), auto_now_add=True)
    modified_at = models.DateTimeField(_('modified at'), auto_now=True)

    class Meta:
        db_table = 'experience'
        verbose_name = _('experience')
        verbose_name_plural = _('experiences')
        ordering = ('-start_date',)

    def __str__(self):
        return getattr(self, 'title', '')

    @property
    def experience(self):
        if self.end_date:
            return (self.end_date - self.start_date).days
        else:
            return (datetime.datetime.now().date() - self.start_date).days

    def get_formated_experience(self):
        days = self.experience
        total_months = round(days/30)
        years = int(total_months/12)
        months = round(((total_months/12)%1)*12)
        year_txt = 'years' if years > 1 else 'year'
        month_txt = 'months' if months > 1 else 'month'
        return "%s %s %s %s" %(years, year_txt, months, month_txt)

位置模型

class Location(models.Model):
    """
    """
    id = models.TextField(primary_key=True)
    display_name = models.TextField(null=True, blank=True)
    latitude = models.DecimalField(max_digits=15, decimal_places=10, null=True, blank=True)
    longitude = models.DecimalField(max_digits=15, decimal_places=10, null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    objects = LocationManager()

【问题讨论】:

  • 请出示您的序列化代码。
  • 我已经用我的脚本编辑了我的问题,所以请看一眼:)
  • 你可以在你的模型中设置blank=True
  • 感谢 Fazil Zaid,

标签: django validation django-rest-framework


【解决方案1】:

根据快照,您会收到两种类型的验证错误。

  1. 必填字段
  2. 期望字典并得到一个字符串

当您在模型中设置了必填字段时,会发生必填字段错误。您可以通过在模型中为该字段添加 blank=True 来更改此设置。 对于第二个错误,您的序列化程序需要一个字典并且您正在发送一个字符串。您可以通过编写自定义创建方法来删除此验证。

class ExperienceSerializer(serializers.HyperlinkedModelSerializer):

    user_location = LocationField()
    location = LocationField()

    class Meta:
        model = Experience
        fields = ('id', 'company_name', 'company', 'description', 'location',
                'title', 'start_date', 'end_date', 'is_current', 'user_location')

    def create(self, validated_data):
        # you create code for that models.

你的序列化器会是这样的

class ProfessionalRegistrationSerializer(serializers.HyperlinkedModelSerializer):

    password = serializers.CharField(max_length=20, write_only=True)
    experiences = ExperienceSerializer(required=False)
    email = serializers.EmailField()
    first_name = serializers.CharField(max_length=30)
    last_name = serializers.CharField(max_length=30)

    class Meta:
        model = User
        fields = ('url', 'id', 'first_name', 'last_name', 'email', 'password',
        'experiences', 'headline')

    def validate_email(self, value):
        from validate_email_address import validate_email
        if User.all_objects.filter(email=value.lower()).exists():
            raise serializers.ValidationError('User with this email already exists.')
        # if not validate_email(value.lower(), check_mx=True):
        #     raise serializers.ValidationError('It looks like you may have entered an incorrect email address.')
        return value.lower()

    def create(self, validated_data):
        experiences = validated_data.get('experiences')
        password = validated_data.get('password')
        email = validated_data.get('email')
        user = User.objects.create(
            username=email.lower(),
            email=email.lower(),
            role_id=1)
        user.set_password(password)
        user.save()
        user_location = experiences.get('user_location')
        location_object = None
        if user_location:
            location_object, created = Location.objects.get_or_create(display_name=user_location.get('display_name'), latitude= user_location.get('latitude'), longitude=user_location.get('longitude'))
        user_experience = Experience.objects.create(user=user, company_name=experiences.get('company_name'), location=location_object)
        return user 

class ExperienceSerializer(serializers.HyperlinkedModelSerializer):

    user_location = LocationField()
    location = LocationField()

    class Meta:
        model = Experience
        fields = ('id', 'company_name', 'company', 'description', 'location',
                'title', 'start_date', 'end_date', 'is_current', 'user_location')

【讨论】:

  • 请看 class ProfessionalRegistrationSerializer(serializers.HyperlinkedModelSerializer): 这里已经定义了 def create(self,validated_data): 请指出应该在哪里更改以删除“期望字典并得到一个字符串”的验证我我是 django 新手,请帮帮我:)
  • 您提到的序列化程序是用于用户模型的。所以创建函数将用于用户对象。您要删除验证的字段属于体验模型,因此创建函数将用于体验的序列化程序。
  • 您想解释一下“validated_data”的工作原理吗?
  • validated_data 是一个字典,其中包含该序列化程序的所有有效数据。您不需要将其传递给序列化程序。当您调用 serializerr.save() 时,将自动调用该 create 函数
  • 感谢您的回复 M Hassan。为什么将 ** 放在 **validated_data 之类的地方?例如:return YourModel.objects.create(user=self.context.get('user'), **validated_data)
猜你喜欢
  • 1970-01-01
  • 2010-09-26
  • 1970-01-01
  • 2017-09-18
  • 2011-11-14
  • 2016-03-09
  • 1970-01-01
  • 2023-02-15
  • 1970-01-01
相关资源
最近更新 更多