This is the 26th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Vue+Django travel network project back end implementation

Shuffling figure

Configuring the Database

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql'.'NAME': 'trip'.'USER': 'root'.'PASSWORD': '123456'.'HOST': '127.0.0.1'.'PORT': 3306,}}Copy the code

Create an

startapp system
Copy the code

Creating a database

Writing model

class Slider(models.Model) :
    name=models.CharField('name',max_length=32)
    desc=models.CharField('description',max_length=100,null=True,blank=True)
    types=models.SmallIntegerField('Display position',default=10)
    img=models.ImageField('Picture address',max_length=255,upload_to='%Y%m/slider')
    reorder=models.SmallIntegerField('Sort field',default=0,help_text="The higher the number, the higher the number.")
    start_time=models.DateTimeField('Effective start time',null=True,blank=True)
    end_time=models.DateTimeField('Effective End Time',null=True,blank=True)
    target_url=models.CharField('Jump address',max_length=255,null=True,blank=True)
    is_valid=models.BooleanField('Valid or not',default=True)
    created_at=models.DateTimeField('Creation time',auto_now_add=True)
    updated_at=models.DateTimeField('Modification time',auto_now=True)

    class Meta:
        db_table='system_slider'
        ordering=['-reorder']

Copy the code

Registration application

Synchronizing databases

makemigrations
migrate
Copy the code

Interface to write

from django.http import HttpResponse, JsonResponse
from django.shortcuts import render

# Create your views here.
from system.models import Slider


def slider_list(request) :
    {"meta":[] "objects":[]} ""
    data ={
        'meta': {},'objects':[]
    }
    querset=Slider.objects.filter(is_valid=True)
    for item in querset:
        data['objects'].append({
            'id':item.id.'img_url': item.img.url,
            'target_url':item.target_url,
            'name': item.name
        })
    return JsonResponse(data)

Copy the code

Utl set

system/urls.py

from django.urls import path

from system import views

urlpatterns = [
    path('slider/list', views.slider_list),
]
Copy the code

Root urls. Py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    # System module
    path('system/',include('system.urls')))Copy the code

test

You need to add data to the database before testing

attractions

The new application

startapp sight
Copy the code

registered

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

Writing model

class Sight(models.Model) :
    name = models.CharField('name',max_length=64)
    desc=models.CharField('description',max_length=255)
    main_img=models.ImageField('the main figure',upload_to='%Y%m/sight/',max_length=255)
    banner_img=models.ImageField('Master View of Details',upload_to='%Y%m/sight/',max_length=255)
    content=models.TextField('details')
    score=models.FloatField('score',default=5)
    min_price=models.FloatField('Rock-bottom price',default=0)
    province=models.CharField('province',max_length=32)
    city=models.CharField('the city',max_length=32)
    area=models.CharField('District/county',max_length=32,null=True)
    town=models.CharField('the villages and towns',max_length=32,null=True)
    is_top=models.BooleanField('Is it a selected attraction?',default=False)
    is_hot=models.BooleanField('Is it a popular destination?',default=False)
    is_valid=models.BooleanField('Valid or not',default=True)
    created_at=models.DateTimeField('Creation time',auto_now_add=True)
    updated_at=models.DateTimeField('Modification time',auto_now=True)
    class Meta:
        db_table:'sight'
        ordering=['-updated_at']
Copy the code

Database synchronization

makemigrations
migrate
Copy the code

Interface to write

Root utls. Py

urlpatterns = [
    path('admin/', admin.site.urls),
    # System module
    path('system/',include('system.urls')),
    # attractions
    path('sight/',include('sight.urls')))Copy the code

sight urls.py

from django.urls import path

from sight import views

urlpatterns = [
    # Scenic spot list interface
    path('sight/list/', views.SightListView.as_view()),
]
Copy the code

views.py

from django.db.models import Q
from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views.generic import ListView

from sight.models import Sight


class SightListView(ListView) :
    """ List of Attractions ""
    # 5 data per page
    paginate_by = 5

    def get_queryset(self) :
        # rewrite the query method
        query=Q(is_valid=True)
        # Hot spots
        is_hot = self.request.GET.get('is_hot'.None)
        if is_hot:
            query=query & Q(is_hot=True)
        # Selected attractions
        is_top = self.request.GET.get('is_top'.None)
        if is_top:
            query = query & Q(is_top=True)
        queryset=Sight.objects.filter(query)
        return queryset

    def render_to_response(self, context, **response_kwargs) :
        page_obj=context['page_obj']
        data = {
            'meta': {
                'total_count':page_obj.paginator.count,
                'page_count':page_obj.paginator.num_pages,
                'current_page':page_obj.number,
            },
            'objects': []}for item in page_obj.object_list:
            data['objects'].append({
                'id':item.id.'name':item.name,
                'main_img':item.main_img.url,
                'score':item.score,
                'province':item.province,
                'min_price':item.min_price,
                'city':item.city,
                'comment_count':0
            })
        return JsonResponse(data)
Copy the code

test

Interworking with multicast diagram interfaces

ajax.js

import axios from 'axios'

export const ajax = axios.create({
  headers: {
    source: 'h5'.icode: 'acbd'.'Content-Type': 'application/x-www-form-urlencoded'
  },
  withCredentials: true
})
ajax.interceptors.request.use(function (config) {
  // What to do before sending the request
  console.log('Request intercepted')
  return config
}, function (error) {
  // What to do about the request error
  return Promise.reject(error)
})

ajax.interceptors.response.use(function (response) {
  // What to do with the response data
  console.log('Response intercepted')
  return response
}, function (error) {
  // Do something about the response error
  if (error.response) {
    if (error.response.status === 401) {
      window.alert('Not logged in, about to jump to login page')}else if (error.response.status === 500) {
      window.alert('Server is busy, please try again later')}}return Promise.reject(error)
})

Copy the code

apis.js

// Store all interface addresses in the project

const apiHost = 'http://localhost:8080/api'
const AccountsApis = {
  loginUrl: '/'.logoutUrl: ' '
}

/** * System module interface */
const SystemApis = {
  sliderListUrl: apiHost + '/system/slider/list/'
}

export {
  AccountsApis,
  SystemApis
}

Copy the code

vue.config.js

module.exports = {
  devServer: {proxy: {
      '/api': {
        target:'http://127.0.0.1:8000/'.changeOrigin: true.pathRewrite: {
          '^/api': ' '   // Rewrite is required to rewrite the URL
        }
      }
    }
  }
}
  
Copy the code

Banner component

<template> <! -- Rotation chart --><div class="home-banner-box">
    <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
      <van-swipe-item v-for="item in bannerList"
        :key="item.id">
        <img :src="item.img_url" alt="">
      </van-swipe-item>
    </van-swipe>
  </div>
</template>
<script>
import { ajax } from '@/utils/ajax'
import { SystemApis } from '@/utils/apis'
export default {
  data () {
    return {
      bannerList: []}},methods: {
    /** * get data */
    getDataList () {
      ajax.get(SystemApis.sliderListUrl).then(res= > {
        console.log('res', res)
        this.bannerList = res.data.objects
      })
    }
  },
  created () {
    this.getDataList()
  }
}
</script>
<style lang="less">
.home-banner-box {
  img {
    width: 100%;
    height: auto; }}</style>

Copy the code

Effect:

Scenic spot list Interface interconnection

apis.js

// Store all interface addresses in the project

const apiHost = 'http://localhost:8080/api'
const AccountsApis = {
  loginUrl: '/'.logoutUrl: ' '
}

/** * System module interface */
const SystemApis = {
  // Multicast list
  sliderListUrl: apiHost + '/system/slider/list/'
}

/** * attractions module */
const SightApis = {
  // List of attractions
  sightListUrl: apiHost + '/sight/sight/list/'
}
export {
  AccountsApis,
  SystemApis,
  SightApis
}

Copy the code

Components are Fine. Vue

<template> <! -- Selected scenic spots --><div class="home-fine-box">
      <! Navigation -- - >
        <van-cell
          icon="location-o"
          title="Top recommendations"
          title-style="text-align:left"
          value="The Whole list."
          is-link />
        <! List -- - >
        <div class="box-main">
          <SightItem v-for="item in dataList"
          :key="item.id"
          :item="item"/>
        </div>
    </div>
</template>
<script>
import { ajax } from '@/utils/ajax'
import { SightApis } from '@/utils/apis'
import SightItem from '@/components/common/ListSight'
export default {
  components: {
    SightItem
  },
  data () {
    return {
      dataList: []}},methods: {
    getDataList () {
      ajax.get(SightApis.sightListUrl, {
        params: {
          is_top: 1
        }
      }).then(({ data }) = > {
        this.dataList = data.objects
      })
    }
  },
  created () {
    this.getDataList()
  }
}
</script>
<style lang="less">
.home-fine-box {
  padding: 0 10px;
  .van-cell {
    padding: 10px 0;
  }
  .box-main {
    padding-bottom: 50px; }}</style>

Copy the code

Hot.vue

<template>
    <div class="home-hot-box">
        <! Navigation -- - >
        <van-cell
          icon="/static/home/hot/fire.png"
          title="Top recommendations"
          title-style="text-align:left"
          value="The Whole list."
          is-link />
        <! List -- - >
        <div class="box-main">
            <a href="#" class="hot-item"
              v-for="item in dataList"
              :key="item.id">
                <div class="img">
                    <span></span>
                    <img :src="item.main_img" alt="">
                </div>
                <h5 class="van-ellipsis">{{ item.name }}</h5>
                <div class="line-price">
                    <span class="price">${{item. Min_price}}</span>since</div>
            </a>
        </div>
    </div>
</template>
<script>
import { ajax } from '@/utils/ajax'
import { SightApis } from '@/utils/apis'
export default {
  data () {
    return {
      dataList: []}},methods: {
    getDataList () {
      ajax.get(SightApis.sightListUrl, {
        params: {
          is_hot: 1
        }
      }).then(({ data }) = > {
        this.dataList = data.objects
      })
    }
  },
  created () {
    // Query interface data
    this.getDataList()
  }
}
</script>
<style lang="less">
.home-hot-box {
  padding: 0 10px;
  .van-cell {
    padding: 10px 0;
  }
  .box-main {
    width: 100%;
    display: flex;
    padding-top: 10px;
    overflow-x: scroll;
  }
  .hot-item {
    display: flex;
    flex-direction: column;
    width: 100px;
    margin-right: 10px;
    padding-bottom: 10px;

    .img {
      position: relative;

      span {
        position: absolute;
        left: 0;
        top: 0;
        display: inline-block;
        width: 42px;
        height: 20px;
        z-index: 10;
      }

      img {
        width: 100px;
        height: 100px; }}h5 {
      color: # 212121;
      padding: 2px 0;
      font-size: 12px;
      margin: 0;
    }

    .line-price {
      color: # 212121;
      font-size: 12px;
      .price {
        color: #f50;
        font-size: 13px; }} &:nth-child(1) .img span {
      background: url(/static/home/hot/top1.png) no-repeat;
      background-size: 100% auto;
    }
    &:nth-child(2) .img span {
      background: url(/static/home/hot/top2.png) no-repeat;
      background-size: 100% auto;
    }
    &:nth-child(3) .img span {
      background: url(/static/home/hot/top3.png) no-repeat;
      background-size: 100%auto; }}}</style>

Copy the code

Effect: