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: