【问题标题】:How to include custom functions in django serializers?如何在 django 序列化程序中包含自定义函数?
【发布时间】:2020-02-05 10:43:10
【问题描述】:

我一直在尝试各种方法,但即使在这里提出我以前的问题,似乎仍然无法完成这项任务。问题是,我正在尝试使用 rest 将用户在 django 管理页面上输入的数据转换为 json 数据。但在将数据转换为 json 之前,我有 2 个自定义函数来验证使用 PyPI 包的用户输入的电子邮件和电话号码字段,我需要这些函数来运行管理页面上输入的文本值。我不知道将我的 2 个函数放在我的 python 文件中的哪个位置,无论是在 models.py 还是 serializers.py 中,我实际上都尝试了这两种方法,但似乎无法让它工作。

/* models.py */ 

import re
import phonenumbers
from django.db import models
from phonenumbers import carrier
from validate_email import validate_email


class razer(models.Model):
    emailplus = models.EmailField()
    country = models.CharField(max_length=2)
    phone_number = models.CharField(max_length=100)

    def clean_emailplus(self):
        email = self.cleaned_data.get("emailplus")
        if not validate_email(email, check_mx=True, verify=True):
            raise models.ValidationError("Invalid email")
        return email

    def clean_phone_number(self):
        phone_number = self.cleaned_data.get("phone_number")
        clean_number = re.sub("[^0-9&^+]", "", phone_number)
        # alpha_2 = self.cleaned_data.get("country")
        alpha_2 = self.cleaned_data.get("country")
        z = phonenumbers.parse(clean_number, "%s" % (alpha_2))
        if len(clean_number) > 15 or len(clean_number) < 3:
            raise forms.ValidationError(
                "Number cannot be more than 15 or less than 3")
        if not phonenumbers.is_valid_number(z):
            raise forms.ValidationError(
                "Number not correct format or non-existent")
        if carrier.name_for_number(z, "en") == '':
            raise forms.ValidationError("Please enter a mobile number")
        return phonenumbers.format_number(
            z, phonenumbers.PhoneNumberFormat.E164)

    def __str__(self):
        return self.emailplus

/* serializers.py */ 
import re
import phonenumbers
from rest_framework import serializers
from .models import razer
from phonenumbers import carrier
from validate_email import validate_email


class razerSerializer(serializers.ModelSerializer):

    class Meta:
        model = razer
        fields = ('emailplus', 'country', 'phone_number')

/* views.py */ 
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import razer
from .serializers import razerSerializer


class razerList(APIView):

    def get(self, request):
        razer1 = razer.objects.all()
        serializer = razerSerializer(razer1, many=True)
        return Response(serializer.data)

    def post(self):
        pass

另外,如果我将 phonenumber 和 email 字段放在我的 serializers.py 中,如 phone_number = serializers.CharField(),然后也放入 2 个自定义函数,我是否必须将序列化程序注册为模型,我应该做什么? views.py 更改为当前使用的 models.py 。请告诉我应该进行哪些更改,因为我需要验证用户在注册模型的管理页面上输入的文本值,或者通过用户可以单独输入文本的其他方法。

【问题讨论】:

  • Validator 是您正在寻找的。​​span>
  • 你的问题不是很清楚。如果您想在将数据保存到数据库之前验证在管理员中输入的数据,那么序列化程序肯定与它无关吗?
  • 你能给我一个例子或者你会如何重写代码吗?它很复杂,因为我的函数需要 get 方法从文本字段中获取文本,然后运行验证。我不知道如何从用户那里获取文本。
  • @DanielRoseman 任何一种方法都可以工作,无论是通过在保存到数据库或序列化程序之前进行验证,只要它通过函数运行。
  • @ĐàoMinhHạt 我必须做验证器=['clean_emailplus']?

标签: python django serialization django-rest-framework


【解决方案1】:

如果你正在创建一个 Django REST 框架应用程序,你需要使用序列化器中的 validate 方法。

def validate(self, data):
        # clean the data
        return data

【讨论】:

  • 在这个函数中,是否可以使用get()方法从用户那里获取文本?
  • 您的项目是基于 DRF 的项目吗?如果是,一切都在数据参数本身中可用。
  • 所以我不再使用 models.py 并将所有文本字段传输到序列化程序对吗?只有这样我才能使用这个验证方法?
  • 是的。请参阅此文档以获取详细帮助。 django-rest-framework.org/api-guide/serializers/#validation
  • 对不起,你能告诉我你将如何重写代码,比如更改序列化程序和views.py吗?
【解决方案2】:

您可以在序列化中为emailplus 字段创建一个custom validator

    def clean_emailplus(value):
        email = value
        if not validate_email(email, check_mx=True, verify=True):
            raise serializers.ValidationError("Invalid email")

    class razerSerializer(serializers.ModelSerializer):
        emailplus = serializers.StringField(validators=[clean_emailplus])

        class Meta:
            model = razer
            fields = ('emailplus', 'country', 'phone_number')

【讨论】:

    猜你喜欢
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 2014-07-08
    • 2013-08-03
    • 1970-01-01
    相关资源
    最近更新 更多