验证POST请求(Vue+DRF)

2024-04-25 18:01:04 发布

您现在位置:Python中文网/ 问答频道 /正文

下面是请求的预期流程:

  1. 用户通过html表单创建一个新的Language。[√]
  2. Vue通过axios将向drf发出POST请求。[√]
  3. Drf将验证POST请求中的数据(查看语言名称/id/etc是否已经存在)[x]
  4. 如果通过验证,则创建新语言。[十]

我现在被困在#3。你知道吗

我试着把这个放在我的LanguageViewSet

def post(self, request):
    language = request.data.get('language')
    serializer = LanguageSerializer(data=language)
    if serializer.is_valid(raise_exception=True):
        language_saved = serializer.save()
    return Response({"success": "Language '{}' created successfully!".format(language_saved.name)})

但是,这在某种程度上不起作用,并且被完全忽略,因为:

  1. 我试着对post函数进行注释,但是如果我通过axios在LanguageViewSet上调用post请求,它仍然会进行post。可能是内置的POST功能?你知道吗
  2. 如果函数存在,请注意我使用了language = request.data.get('language'),这意味着在我的axios上,要发送的数据的名称应该是language,对吗?否则它将忽略POST请求。我在axios中使用了created_lang,启动了POST-req,但它仍然没有出现任何错误,就好像它完全忽略了我的POST函数一样。你知道吗
  3. 如果我试着发布一种新的语言,它的名字已经在数据库中注册了,它仍然会创建一个重复的记录。你知道吗

请原谅我的天真,我对drf和django完全陌生:<

这是我的密码:

Language型号:

class Language(models.Model):
    name = models.CharField(max_length=100, default='New Language')
    def __str__(self):
        return self.name

它的serializer

class LanguageSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Language
        fields = ['id', 'name']

view

class LanguageViewSet(viewsets.ModelViewSet):
    queryset = Language.objects.all().order_by('name')
    serializer_class = LanguageSerializer

    def get_queryset(self):
        queryset = Language.objects.all().order_by('name')
        lang = self.request.query_params.get('lang','')
        if lang:
            return Language.objects.filter(pk=lang)
        else:
            return queryset    

url

router = routers.DefaultRouter()
router.register(r'languages', views.LanguageViewSet)

在我的前端,这是我的表格:

<form @submit.prevent="PostLanguage" class="mt-3" action='' method="POST">
    <input type="text" v-model="created_lang.name" name="name" id="name" placeholder="Language Name" autocomplete="off" required>
    <input type="submit" value="Post">
</form>

将通过以下简单的Vue脚本发布:

PostLanguage(){
    let params = Object.assign({}, this.created_lang)
    axios.post(
        'http://127.0.0.1:8000/api/languages/', params
    )
    .then(response=>{
        console.log(response)
        this.GetLanguages()
        this.created_lang.name = ''
    })
    .catch(error => {
        console.log(error)
    })
}

更新

我试过这个:

class LanguageSerializer(serializers.ModelSerializer):
class Meta:
    model = Language
    fields = ['id', 'name']

def validate_name(self, value):
    existed_language = Language.objects.filter(name=value).get()
    if existed_language.name == value:
        return Response(status=400)
    else:
        return value

如果POST中的name数据是新的(它没有在数据库中使用),那么它将返回它的value,从而创建一种新的语言。但是,如果它已经存在,我尝试返回一个响应,但它将创建一个名称为<Response status_code=400, "text/html; charset=utf-8">的语言。我知道这有点可笑,但我认为这是朝着正确方向迈出的一步。你知道吗


Tags: nameself语言langgetreturnvaluepost
1条回答
网友
1楼 · 发布于 2024-04-25 18:01:04

如果语言在模型中是唯一的,那么在模型定义中添加unique true。你知道吗

class Language(models.Model):
    name = models.CharField(max_length=100, default='New Language', unique=True)
    def __str__(self):
        return self.name

这将导致序列化程序.validate失败,不会创建重复的语言。你知道吗

更新

序列化程序中的validate\u name在执行验证逻辑后返回字段的值。所以可以用raise serializers.ValidationError("Language already exist")而不是Response(400)语句来更新它。你知道吗

相关问题 更多 >

    热门问题