Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Django Rest与Vue.js前端配对时不允许使用(PUT)方法_Vue.js_Django Rest Framework_Restapi - Fatal编程技术网

使用Django Rest与Vue.js前端配对时不允许使用(PUT)方法

使用Django Rest与Vue.js前端配对时不允许使用(PUT)方法,vue.js,django-rest-framework,restapi,Vue.js,Django Rest Framework,Restapi,我正在尝试使用Vue.js向我的RestAPI发出PUT请求。它完全可以在我的ModelViewSet视图中工作,但是当我通过Vue.js尝试它时,我遇到了方法不允许(PUT)。我还可以在同一个onSubmit函数中使用“POST”。 以下是my QuestionEditor.vue中提交函数的代码: <template> <div class="container mt-2"> <h1 class="mb-3">Ask a Quest

我正在尝试使用Vue.js向我的RestAPI发出PUT请求。它完全可以在我的ModelViewSet视图中工作,但是当我通过Vue.js尝试它时,我遇到了方法不允许(PUT)。我还可以在同一个onSubmit函数中使用“POST”。 以下是my QuestionEditor.vue中提交函数的代码:

<template>
    <div class="container mt-2">
        <h1 class="mb-3">Ask a Question</h1>
        <form @submit.prevent="onSubmit">
            <textarea v-model="question_body" class="form-control" placeholder="What do you want to ask?" row="3">
            </textarea>
            <br>
            <button type="submit" class="btn btn-success">
                Publish
            </button>
        </form>
        <p v-if="error" class="muted mt-2">{{ error }}</p>
    </div>
</template>

<script>
import { apiService } from "../common/api.service.js"
export default {
    name: "QuestionEditor",
    props: {
        slug: {
            type: String,
            required: null
        }
    },
    data() {
        return{
            question_body: null,
            error: null
        }
    },
    methods: {
        onSubmit() {
            if (!this.question_body){
                this.error = "You can't send an empty question!";
            } else if (this.question_body.length > 240) {
                this.error = "Exceeding 240-character limit!";
            } else {
                let endpoint = "/api/questions/";
                let method = "POST";
                if (this.slug !== undefined) {
                    endpoint += `${ this.slug }/`;
                    method = "PUT";
                }
                apiService(endpoint, method, { content: this.question_body })
                    .then(question_data => {
                        this.$router.push({
                            name: 'Question',
                            params: {slug: question_data.slug}
                        })
                    })
            }
        }
    },
    async beforeRouteEnter(to, from, next){
        if (to.params.slug !== undefined) {
            let endpoint = `/api/questions/${to.params.slug}/`;
            let data = await apiService(endpoint);
            return next(vm => (vm.question_body = data.content));
        } else{
            return next();
        }
    },
    created() {
        document.title = "Editor - QuestionTime";
    }
}
</script>

<style scoped>

</style>
最后是api视图:

class QuestionViewSet(viewsets.ModelViewSet):
    queryset = Question.objects.all().order_by("-created_at")
    lookup_field = "slug"
    serializer_class = QuestionSerializer
    permission_classes = [IsAuthenticated, IsAuthorOrReadOnly]

    def perform_create(self, serializer):
        serializer.save(author=self.request.user)
更新:问题序列化程序:

class QuestionSerializer(serializers.ModelSerializer):
    author = serializers.StringRelatedField(read_only=True)
    created_at = serializers.SerializerMethodField(read_only=True)
    slug = serializers.SlugField(read_only=True)
    answers_count = serializers.SerializerMethodField()
    user_has_answered = serializers.SerializerMethodField()

    class Meta:
        model = Question
        exclude = ["updated_at"]

    def get_created_at(self, instance):
        return instance.created_at.strftime("%B %d %Y")

    def get_answers_count(self, instance):
        return instance.answers.count()

    def get_user_has_answered(self, instance):
        request = self.context.get("request")
        return instance.answers.filter(author=request.user).exists()
api的url.py:

from django.urls import include, path
from rest_framework.routers import DefaultRouter
from .views import QuestionViewSet, AnswerCreateAPIView, AnswerListAPIView, AnswerRUDAPIView, AnswerLikeAPIView

router = DefaultRouter()
router.register(r"questions", QuestionViewSet)

urlpatterns = [
    path("", include(router.urls)),
    path("questions/<slug:slug>/answer/", AnswerCreateAPIView.as_view(), name="answer-create"),
    path("questions/<slug:slug>/answers/", AnswerListAPIView.as_view(), name="answer-list"),
    path("answers/<int:pk>/", AnswerRUDAPIView.as_view(), name="answer-detail"),
    path("answers/<int:pk>/like/", AnswerLikeAPIView.as_view(), name="answer-like"),
]

解决了我从WebpackVersion1Alpha降级到了0.4.3,现在一切都正常了。使用半开发版本是我的错误。

我想我现在可能知道发生了什么

  • 您需要在序列化程序中添加pk字段(
    Meta
    中的
    fields
    必须具有
    id
    字段)

  • 或者你的端点是错误的

  • 如果您在这里所做的只是更改方法,那么这是不够的,因为您发布到
    /resource
    ,但将其放到
    /resource/

    因此,不允许放入
    /resource

    您可以在
    ModelViewSet
    中重写此逻辑,从body获取
    id
    ,但我不建议这样做


    编辑:我刚刚注意到您添加了
    endpoint+=${this.slug}/。您能在这里展示一下PUT的端点是什么样子的吗?用这个鼻涕虫。这是序列化程序中的正确id吗?

    我认为您必须在服务器端允许cors头
    pip安装django cors头文件

    在django app settings.py中:

    INSTALLED_APPS = [
        'corsheaders',
    ]
    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware',
    ]
    CORS_ORIGIN_ALLOW_ALL = True
    

    看起来您的问题在权限中

    permission_classes = [IsAuthenticated, IsAuthorOrReadOnly]
    

    我的猜测是你的
    是作者造成的。你能为它提供源代码吗?

    我想我们也需要你的DRF代码。endpoint+=`${this.slug}/将所需的id(在本例中是slug)添加到端点,有趣的是问题实例可以更新,直接在浏览器中使用相同的端点。如果您确定PUT
    api/questions/
    有效,并且在后端进行了测试,并且端点与前端完全相同,那么我不知道出了什么问题。完全正确!这是我检查的第一件事。真奇怪,还是有同样的问题!请记住,我可以在Rest视图中放置来自同一端点的更新,但不能通过Vue.js。
                } else {
                    let endpoint = "api/questions/";
                    let method = "POST";
                    if (this.slug !== undefined) {
                        endpoint += `${ this.slug }/`;
                        method = "PUT";
                    }
                    apiService(endpoint, method, { content: this.question_body })
                        .then(question_data => {
                            this.$router.push({
                                name: 'Question',
                                params: {slug: question_data.slug}
                            })
                        })
    
    INSTALLED_APPS = [
        'corsheaders',
    ]
    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware',
    ]
    CORS_ORIGIN_ALLOW_ALL = True
    
    permission_classes = [IsAuthenticated, IsAuthorOrReadOnly]