我正在尝试结合Django + Vuejs。 到目前为止,我已经找到了两种方法。这里:和这里:using vue inside Django templates和这里:totally splitting server (django) and client(vuejs)
使用第二种方法时,我一直在为提交一个简单的表格而苦苦挣扎(可能还因为我是Web开发人员中的新手)。您能帮我一下,告诉我哪种方法更好。
这是我来自Django的views.py:
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login, authenticate
from django.shortcuts import render, redirect
from rest_framework.response import Response
from rest_framework import status
from rest_framework.renderers import JSONRenderer
from rest_framework.decorators import api_view, renderer_classes
from .serializers import *
from .forms import SignUpForm
from .models import NighterProfile
from django.contrib.auth.models import User
import json
@login_required
def home(request):
return render(request, 'home.html')
@api_view(['GET', 'POST'])
@renderer_classes((JSONRenderer,))
def signUp(request):
if request.method == 'POST':
form = json.loads(request.body)
form = SignUpForm(form)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password)
login(request, user)
return redirect('home')
else:
formFields = (SignUpForm()).fields
form = {}
for field in formFields.keys():
form[field] = field
return Response(form)
当我遇到错误时,我使用request.body而不是request.POST,然后我读到它只能用于请求中发送的表单。
这是我来自Vue的SignUp.vue:
<template>
<v-layout column>
<v-flex class="block_form">
<BlockForm title="Sign Up">
<div v-for="field in fields" v-if="fieldsExpected.includes(field)">
<v-text-field v-if="field!=='password1'" :label="field" :name="field" :id="'id_' + field" v-model="formSent[field]"></v-text-field>
<div v-if="field==='password1'">
<v-text-field label="password" name="password1" id="id_password1" v-model="formSent['password1']"></v-text-field>
<v-text-field label="password confirmation" name="password2" id="id_password1" v-model="formSent['password2']"></v-text-field>
</div>
<br>
</div>
<div class="danger-alert" v-html="error"/>
<br>
<v-btn dark class="cyan" @click="signUp">
Sign Up
</v-btn>
<div class="row">
<div class="input-field col s12">
<v-btn dark class="red" id="google" @click="authenticate('google')">Google+</v-btn>
<v-btn dark class="blue" id="facebook" @click="authenticate('facebook')">
Facebook
</v-btn>
</div>
</div>
</BlockForm>
<hr>
<p>
Need an account?
<v-btn to="login">
Login
</v-btn>
</p>
<p>
Or go
<v-btn to="home">
Home
</v-btn>.
</p>
</v-flex>
</v-layout>
</template>
<script>
import AuthenticationService from '@/services/AuthenticationService'
import MainConnectionsService from '@/services/MainConnectionsService'
import axios from 'axios'
export default {
data () {
return {
fields:{},
fieldsExpected:['email', 'username', 'password1'],
formSent: {},
email: "",
username:"",
password: "",
error: null
}
},
async mounted() {
try {
const afterBaseURL = '/sign-up/'
const response = await MainConnectionsService.get(afterBaseURL)
this.fields = Object.keys(response.data)
} catch(err) {
console.log(err)
}
},
methods: {
async signUp() {
console.log(this.formSent)
try {
const response = await AuthenticationService.signUp(this.formSent)
this.$store.dispatch('setToken', response.data.token)
this.$store.dispatch('setUser', response.data.user)
this.$router.push({
name: 'welcome'
})
} catch (error) {
this.error = error.response.data.error
}
},
async authenticate(provider) {
let accessToken
window.authenticateCallback = function(token) {
accessToken = token;
};
await window.open('https://localhost:8000/authentication/' + provider + '/start');
}
}
}
</script>
<style scoped>
.block_form {
min-width: 600px;
margin: auto;
}
</style>
对于Get REQUEST来说还可以,但是对于帖子,我找不到解决方法。 我得到的错误:
Internal Server Error: /sign-up
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py", line 158, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py", line 156, in _get_response
response = response.render()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/template/response.py", line 106, in render
self.content = self.rendered_content
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/rest_framework/response.py", line 72, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/rest_framework/renderers.py", line 105, in render
allow_nan=not self.strict, separators=separators
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/rest_framework/utils/json.py", line 28, in dumps
return json.dumps(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/rest_framework/utils/encoders.py", line 68, in default
return super(JSONEncoder, self).default(obj)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 180, in default
o.__class__.__name__)
TypeError: Object of type 'SignUpForm' is not JSON serializable
[13/Jul/2018 12:49:14] "POST /sign-up HTTP/1.1" 500 96684
我的主要目标是使用禁忌堆栈,尽管我更喜欢使用第二种方法,因为我认为它可以使我从更多的vuejs功能中受益,但第一种方法似乎是最简单的。 请分享您的建议或经验。