Vue2 django front and back end separation (2. Book management project)

1. Use of django-rest-framework

https://zhuanlan.zhihu.com/p/128976272
In order to facilitate the implementation of the backend, django-rest-framework (DRF) provides many useful features as a common plug-in for django as a backend api service, so this article Also apply it in the demo

1. Enter the command to install on the command line:

pip install django-rest-framework

2. Register the application in the configuration file (drf is actually an app)

insert image description here

3. Serialization model

Create a serializer.py file in the books folder and write the corresponding serializer BooksSerializer:

# books/serializer.py
from rest_framework import serializers
from books.models import Books

class BooksSerializer(serializers.ModelSerializer):
    class Meta:
        model = Books
        fields = '__all__'

Use drf to implement model serialization ( serializer ), which saves data processing when writing interfaces.

4. Write the corresponding view set BooksViewSet in the views.py file to handle the request:

# books/views.py
from rest_framework import viewsets
from books.models import Books
from books.serializer import BooksSerializer


class BooksViewSet(viewsets.ModelViewSet):
    queryset = Books.objects.all()
    serializer_class = BooksSerializer

5. Write the corresponding route mapping in the urls.py file:

# books/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from books import views


router = DefaultRouter()
router.register('books', views.BooksViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

6. Run the back-end project to see the effect, run the command line:

DRF allows us to add, delete, modify and query a certain data class Model through the view set ViewSet, and different operations correspond to different request methods, such as viewing all books using the get method, adding a book using the post method, etc., so that The entire backend service is restful.

python manage.py makemigrations
python manage.py migrate
python manage.py runserver

Thanks to the api visualization interface provided by DRF, the browser accesses 127.0.0.1:8000/api/books/, if the following interface appears and the added data is normal, it means that the basic logic of the backend is ok~ effect on the data.
insert image description here

7. Front-end implementation

The next work will be carried out with the appfront project directory as the root directory, and start to write a little front-end display and form, hoping to achieve two goals, one is to be able to request a list of all books from the backend, and the other is to be able to add a book to the backend data. To put it bluntly, I hope to simply implement the above page with Vue, and then achieve the same function. There is not much explanation here for the functions of each file in the Vue project, you can refer to its documentation system to learn. Here you only need to know that the styles in the welcome page are written in App.vue and components/HelloWorld.vue.
Here directly use HelloWorld.vue to modify, only for functions and not for pages

// appfront/src/components/HelloWorld.vue
<template>
  <div class="hello">
    <h1>{
   
   { msg }}</h1>
    <!-- show books list -->
    <ul>
      <li v-for="(book, index) in books" :key="index" style="display:block">
        {
   
   {index}}-{
   
   {book.name}}-{
   
   {book.author}}
      </li>
    </ul>
    <!-- form to add a book -->
    <form action="">
      输入书名:<input type="text" placeholder="book name" v-model="inputBook.name"><br>
      输入作者:<input type="text" placeholder="book author" v-model="inputBook.author"><br>
    </form>
    <button type="submit" @click="bookSubmit()">submit</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App',
      // books list data
      books: [
        {name: 'test', author: 't'},
        {name: 'test2', author: 't2'}
      ],
      // book data in the form
      inputBook: {
        "name": "",
        "author": "",
      }
    }
  },
  methods: {
    loadBooks () {...}, // load books list when visit the page
    bookSubmit () {...} // add a book to backend when click the button
  },
  created: function () {
    this.loadBooks()
  }
}
</script>
...

npm run serve starts the front-end project, and the browser accesses 127.0.0.1:8080. You can see that the page just written has been updated.
insert image description here

8. Front-end and back-end linkage

Here comes the point! ! The data in the above page is actually the simulated data hard-coded on the front-end page. In this section, we hope to complete the front-end and back-end joint debugging by getting data from the back-end and displaying it on the front-end page. Front-end and back-end joint debugging involves the most cross-domain issues. In order to ensure security, it is usually necessary to follow the same-origin policy, that is, the "protocol, domain name, and port" are all the same. For details, you can refer to related blogs. Here you only need to know The above three are the same to be regarded as homologous.

For the back-end part, for the cross-domain problem of django, the more common method on the Internet is to use the django-cors-headers module to solve it. It cannot be avoided here, and the operation is as follows.

First install the corresponding module on the command line:

pip install django-cors-headers

Then add this module to your project:

# books_demo/settings.py
INSTALLED_APPS = [
    ...
    # demo
    'corsheaders',
    ...
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware', # 需注意与其他中间件顺序,这里放在最前面即可
    ...
]

# 支持跨域配置开始
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True 

The back-end part is in the paragraph. Next, we need to add the logic of the front-end. The Vue framework generally uses the axios module to make network requests. This method is used here. The following is the operation in the front-end project:

First, install the axios module on the command line. If cnpm is not installed, install it with npm:

cnpm install axios

In order to facilitate the management of various logics of api requests, create an api directory under the src directory of the front-end project, and then create api.js and index.js files. The index.js file configures axios:

// appfront/src/api/index.js
import Vue from 'vue'
import Axios from 'axios'

const axiosInstance = Axios.create({
    withCredentials: true
})

// 通过拦截器处理csrf问题,这里的正则和匹配下标可能需要根据实际情况小改动
axiosInstance.interceptors.request.use((config) => {
    config.headers['X-Requested-With'] = 'XMLHttpRequest'
    const regex = /.*csrftoken=([^;.]*).*$/
    config.headers['X-CSRFToken'] = document.cookie.match(regex) === null ? null : document.cookie.match(regex)[1]
    return config
})

axiosInstance.interceptors.response.use(
    response => {
        return response
    },
    error => {
        return Promise.reject(error)
    }
)

Vue.prototype.axios = axiosInstance

export default axiosInstance

The api.js file makes a request to the backend. You can see that obtaining the books list and adding a book each correspond to a request:

// appfront/src/api/api.js
import axiosInstance from './index'

const axios = axiosInstance
export const getBooks = () => {
	return axios.get(`http://localhost:8000/api/books/`)
}
export const postBook = (bookName, bookAuthor) => {
	return axios.post(
		`http://localhost:8000/api/books/`, 
		{'name': bookName, 'author': bookAuthor}
	)}

Then update the processing logic in HelloWorld.vue:

// appfront/src/components/HelloWorld.vue
<script>
import {getBooks, postBook} from '../api/api.js'
export default {
  ...
  methods: {
    loadBooks () {
      getBooks().then(response => {
        this.books = response.data
      })
    }, // load books list when visit the page
    bookSubmit () {
      postBook(this.inputBook.name, this.inputBook.author).then(response => {
        console.log(response)
        this.loadBooks()
      })
    } // add a book to backend when click the button
  },
  ...
}
</script>

So far, an extremely simple function of querying and adding books has been completed~ as shown in the figure below: As you can
insert image description heresee, the data in the list is read from the backend, and the submission database at the frontend can also have corresponding operations, so before and after So far it has been opened.

9. Pack

At this stage, the front and back ends are developed separately, but when it is finally used, the code needs to be combined.

First package the front-end project, here use Vue's automatic packaging

npm run build

insert image description here

You can see that there is an extra dist folder in the front-end project, which is the packaging result of the front-end files. The dist folder needs to be copied to the books_demo project folder.

Then modify the settings.py file accordingly, in fact, it is to help django specify the search address of template files and static files:

# books_demo/books_demo/settings.py
...
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'dist')], # demo add
        ...
    },
]
...
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'dist/static'),
]
..

Finally, configure the corresponding routing of the entry html file in the root urls.py file:

# books_demo/books_demo/urls.py
...
from django.views.generic.base import TemplateView

urlpatterns = [
    ...
    path('', TemplateView.as_view(template_name='index.html'))
]

Restart the project, this time use a browser to access 127.0.0.1:8000, which is the corresponding port of the django service.

It can be seen that the interaction of the project is normal and meets our expectations.

Take a very simple demo as an example. Using django+drf+vue's front-end and back-end separation development mode can basically be regarded as an introduction. With this small demo, whether it is the front-end page or the back-end function, it can be extended accordingly, so as to develop a more complex website.

10. MiddlewareMiddleWare

https://www.runoob.com/django/django-middleware.html rookie tutorial
The essence of middleware is actually a class. Middleware will intercept requests and responses when the client and server interact, and do some processing.
insert image description here

1. Create a middleware class
Create a python file middleware.py in the application, and create a class in it
2. Methods in the middleware class
Several methods in the middleware class:

process_request(self, request)
process_view(self, request, view_func, *view_args, **view_kwargs)
process_response(self, request, response)
process_exception(self, request, exception)

3. Import MiddlewareMixin, inherit

from django.utils.deprecation import MiddlewareMixin
from books import views
class MyMiddleware(MiddlewareMixin):
    def process_request(self, request):
        print('process_request') #在视图之前执行

    def process_view(self, request, view_func, *view_args, **view_kwargs):
        # view_func参数表示 应用的view视图中的一个函数作为参数传进来,view_args作为view函数的参数,中间件会执行这个函数
        print('process_view') #在视图之前执行 顺序执行
		return views.test_middleware2(request)	# 函数在返回时调用
		
    def process_response(self, request, response):
        print('process_response')
        return response	# return response是必须的 #在视图之后 基于请求响应
        
    def process_exception(self, request, exception):
        print(exception) # 在响应之前  如果有报错,打印报错信息

3. Add middleware to the settings.py configuration file
insert image description here
and just write the middleware path

Guess you like

Origin blog.csdn.net/m0_53195006/article/details/126944533