The background,

In our work, we often need to build some web-based projects, such as internal test platform, operation and maintenance system, etc. This article focuses on how to quickly build a web project framework using the back-end Django + front-end vue.js technology stack.

Why use Django and vue.js?

Django is one of the most mature Web frameworks in Python. Due to Python’s ease of use and wide audience, Django is the preferred web development framework for small and medium sized websites due to its ability to quickly develop web applications. Django includes data analysis (Pandas), tasks (Celery), REST API(Django REST framework) ), ORM(Java-like Hibernate), and many other features make it easy for users to meet any site requirements.

Vue. Js is a popular JavaScript MVVM library, which is built with the idea of data-driven and componentization. Compared to angular. js, vue.js also supports features such as two-way binding, mustache tag syntax, and provides a cleaner and easier to understand API that allows you to quickly pick up and use vue.js.

This article uses vue.js as a front-end framework to replace Django’s weak template engine. Django provides an API interface as a server, making the front and back implementations completely separate, making it more suitable for single-page applications.

Two, environmental preparation

Installation environment:

Django:

Python 2.7 +

Django 1.11

Mysql 5.7

Python’s MySQLdb module, etc

It is recommended that python-related modules (including Django) be installed using python’s built-in PIP installer. To install the latest version of Django, run the PIP install Django command

Vue. Js series:

Node. Js 6.1

All Vue modules (including Vue) are installed using node’s NPM package manager

Build a Django project

We’ll start by using Django to build the Web backend API framework.

1. Type the command on the terminal:

django-admin startproject myproject

Directory structure:


2, Go to the root directory of the project and create an app:

python manage.py startapp myapp

Directory structure:


In settings.py under myProject, change the default SQLlite3 database to our mysql database:

# # Database https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = {' default ': {' ENGINE' : 'django. Db. Backends. Mysql', 'NAME' : 'myproject', 'USER' : 'root' and 'PASSWORD' : 'root', 'HOST' : '127.0.0.1'}}Copy the code

Add your app to the installed_apps list:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
     'myapp',
]
Copy the code

4, In the app directory models.py we simply write a model as follows:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models

# Create your models here.
class Book(models.Model):
    book_name = models.CharField(max_length=64)
    add_time = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return self.book_name
Copy the code

There are only two fields, book_name and add_time. If no primary key is specified, Django automatically adds an increment ID as the primary key

5. In the views of app directory, we add two new interfaces. One is that show_books returns the list of all books (using JsonResponse to return the DATA in JSON format that can be recognized by the front end).

# Create your views here.
@require_http_methods(["GET"])
def add_book(request):
    response = {}
    try:
        book = Book(book_name=request.GET.get('book_name'))
        book.save()
        response['msg'] = 'success'
        response['error_num'] = 0
    except  Exception,e:
        response['msg'] = str(e)
        response['error_num'] = 1

    return JsonResponse(response)

@require_http_methods(["GET"])
def show_books(request):
    response = {}
    try:
        books = Book.objects.filter()
        response['list']  = json.loads(serializers.serialize("json", books))
        response['msg'] = 'success'
        response['error_num'] = 0
    except  Exception,e:
        response['msg'] = str(e)
        response['error_num'] = 1

    return JsonResponse(response)
Copy the code

As you can see, with the help of ORM, our interface doesn’t actually need to organize the SQL code itself

6. Add a new urls.py file in the app directory to add our two new interfaces to the route:

from django.conf.urls import url, include import views

urlpatterns = [ url(r’add_book$’, views.add_book, ), url(r’show_books$’, views.show_books, ), ]

  1. We also need to add the urls from the app to the urls from the project to complete the route:
from django.conf.urls import url, include from django.contrib import admin from django.views.generic import TemplateView import myapp.urls urlpatterns = [  url(r'^admin/', admin.site.urls), url(r'^api/', include(myapp.urls)), url(r'^$', TemplateView.as_view(template_name="index.html")), ]Copy the code
  1. At the root of the project, enter the command:

python manage.py makemigrations myapp

python manage.py migrate

The book table has been created automatically:


  1. At the root of the project, enter the command:

python manage.py runserver

Start the service and test the two interfaces we just wrote with Postman:

add_book


show_books


4. Build vue.js front-end project

1. Install vuE-CLI scaffolding tools with NPM first (VUe-CLI is the official scaffolding tool that can quickly help you frame your VUE project) :

    `npm install -g vue-cli`
Copy the code

After installation, create a new front-end project directory under the project root directory:

Vue-init webpack AppFront // We need vue-router to do front-end routingCopy the code

Enter the appFront directory and run the following command:

NPM install // Installs node dependencies required by vueCopy the code

Now we can see that the entire file directory structure looks like this:


2. The directory SRC contains entry file main.js and entry component app. vue, etc. The file with suffix vue is a single file component defined by vue. js framework, in which the content in the tag can be understood as htML-like page structure content, the content in the tag is the content in js methods and data, and the content in CSS style:


3. Create a component named library.vue in the SRC/Component folder and call the API we wrote on Django to add books and display information about books. For style components, we use element-UI, which is a set of functional style components that specifically match vue.js framework. Because the component coding involves a lot of JS, HTML, CSS knowledge, is not the focus of this article, so only part of the code is posted here:


SRC /router/index.js/Home/vue /router/index.js/Home/vue /router


5. If the list fails to capture data, a cross-domain problem may occur. Open the browser Console to confirm:


This time we need to inject the header in Django layer, use Django third-party packages Django – cors – headers to solve the problem of cross domain:

       pip install django-cors-headers
Copy the code

Settings. Py modification:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

CORS_ORIGIN_ALLOW_ALL = True
Copy the code
Note the order in which the middleware is addedCopy the code

6, In the front-end project directory, enter NPM run dev to start the node server, the browser will automatically open, we can see the page:


Try adding a new book, the information of the new book will be reflected in the list of the page in real time, thanks to the two-way data binding feature of vue.js.

  1. In the front-end engineering directory, enternpm run buildIf the project has no errors, you can see that all the components, CSS, images, etc. are automatically packaged by Webpack into the dist directory:

Integrate Django with vue.js

So far we have created and written the Django backend and vue.js front-end projects respectively, but they actually run on their own servers, which is inconsistent with our requirements. So we need to point Django’s TemplateView to the front-end dist file we just generated.

1. Go to urls.py in the project directory and use the generic view to create the simplest template controller that returns index.html when “/” is accessed:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include(myapp.urls)),
    url(r'^$', TemplateView.as_view(template_name="index.html")),
]
Copy the code

The previous step used Djangos template system, so you need to configure the template so that Django knows where to find index.html. Under settings.py in the project directory:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['appfront/dist'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
Copy the code

3. We also need to configure the static file search path. Also under settings.py in the project directory:

# Add for vuejs
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "appfront/dist/static"),
]
Copy the code

Python manage.py runserver: python manage.py runserver: python manage.py runserver: python manage.py runserver


Note that the service port is already Django service 8000 instead of Node service 8080

Six, deployment,

Due to the cross-platform nature of Python, it is theoretically possible to simply install all dependencies on the server and copy the project directory directly to the server. Just one thing: if you have configured nginx as a reverse proxy for your project, configure all static file paths in nginx to point to the static file URLS configured in your Django project. You can configure url paths in settings.py:

# Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/ static/'Copy the code

Seven, other

The source code for the instance project can be downloaded from the git directory:

Github.com/rogerlh/dja…