验证POST请求(Vue + DRF)

时间:2019-12-17 09:24:59

标签: python django vue.js django-rest-framework

这是请求的预期流程:

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

我目前停留在#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功能?
  2. 如果有函数,请注意我使用了language = request.data.get('language'),这意味着在我的axios上,要发送的数据的名称应该为language,对吗?否则它将忽略POST请求。我在axios中使用了created_lang,触发了POST请求,但仍然发布它而没有任何错误,好像它完全忽略了我的发布功能。
  3. 如果我尝试发布名称已经在数据库中注册过的新语言,它仍会创建它来制作重复记录。

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

这是我的代码:

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">的语言。我知道这很有趣,但是我认为这是朝正确方向迈出的一步。

1 个答案:

答案 0 :(得分:1)

如果语言在模型中是唯一的,则在模型定义中添加唯一的true。

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

这将导致serializer.validate失败,并且不会创建重复的语言。

更新

序列化程序中的validate_name返回执行验证逻辑后的文件的值。因此,您可以使用raise serializers.ValidationError("Language already exist")而不是Response(400)语句进行更新。