1. 首页 1.1 轮播图
admin站点配置支持图片上传
pip install Pillow
配置代码:
# 访问静态文件的url地址前缀
STATIC_URL = '/static/'
# 项目中存储上传文件的根目录[暂时配置],注意,static目录需要手动创建否则上传文件时报错
MEDIA_ROOT=os.path.join(BASE_DIR,"luffy/static")
# 设置django的静态文件目录
STATICFILES_DIRS = [os.path.join(BASE_DIR,"luffy/static")
]
把Home子应用注册到settings的INSTALLED_APPS中,并在models.py里面创建模型。
INSTALLED_APPS = [...'luffy.apps.home',
]
class BannerInfo(models.Model):"""轮播图"""# upload_to 存储子目录,真实存放地址会使用配置中的MADIE_ROOT+upload_toimage = models.ImageField(upload_to='banner', verbose_name='轮播图', null=True)name = models.CharField(max_length=150, verbose_name='轮播图名称')link = models.CharField(max_length=150, verbose_name='轮播图广告地址')orders = models.IntegerField(verbose_name='显示顺序')is_show=models.BooleanField(verbose_name="是否上架",default=False)is_delete=models.BooleanField(verbose_name="逻辑删除",default=False)class Meta:db_table = 'ly_banner'verbose_name = '轮播图'verbose_name_plural = verbose_namedef __str__(self):return self.name
模型数据迁移:
python manage.py makemigrations
python manage.py migrate
通过如下命令安装xadmin的最新版
在配置文件中注册如下应用
INSTALLED_APPS = [...'rest_framework','xadmin','crispy_forms','reversion',...
]# 修改使用中文界面
LANGUAGE_CODE = 'zh-Hans'# 修改时区
TIME_ZONE = 'Asia/Shanghai'
xadmin有建立自己的数据库模型类,需要进行数据库迁移
python manage.py makemigrations
python manage.py migrate
在总路由中添加xadmin的路由信息
import xadmin
xadmin.autodiscover()# version模块自动注册需要版本控制的 Model
from xadmin.plugins import xversion
xversion.register_models()urlpatterns = [path(r'xadmin/', xadmin.site.urls)
]
创建超级用户
python manage.py createsuperuser
import xadmin
from xadmin import viewsclass BaseSetting(object):"""xadmin的基本配置"""enable_themes = True # 开启主题切换功能use_bootswatch = Truexadmin.site.register(views.BaseAdminView, BaseSetting)class GlobalSettings(object):"""xadmin的全局配置"""site_title = "路飞学城" # 设置站点标题site_footer = "路飞学城有限公司" # 设置站点的页脚menu_style = "accordion" # 设置菜单折叠
xadmin.site.register(views.CommAdminView, GlobalSettings)# 轮播图
from home.models import bannerInfo
class BannerInfoModelAdmin(object):list_display=["name","orders","is_show"]
xadmin.site.register(bannerInfo, BannerInfoModelAdmin)
路由代码
子应用路由:
from django.urls import path,re_path
from . import views
urlpatterns = [
path(r"banner/",views.BannerInfoAPIView.as_view()),
]
总路由:
urlpatterns = [...path('home/', include("home.urls")),# include 的值必须是 模块名.urls 格式,字符串中间只能出现一个圆点
]
from django.db.models import Q
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import bannerInfo
class BannerInfoAPIView(APIView):"""轮播图列表"""def get(self,request):# 获取数据banners &#61; bannerInfo.objects.filter(Q(is_show&#61;True) & Q(is_delete&#61;False)).order_by("-orders")# 调整banners的images字段# 序列化data &#61; []for item in banners:data.append({# 拼接图片的url地址"image": "/static/" &#43; item.image.url,"link":item.link,"orders":item.orders,})return Response(data)前端代码&#xff1a;<template><div class&#61;"banner"><el-carousel trigger&#61;"click" height&#61;"506px"><el-carousel-item v-for&#61;"item in banner_list"><a :href&#61;"item.link"><img :src&#61;"item.image">a>el-carousel-item>el-carousel>div>
template><script>export default {name:"Banner",data(){return {banner_list:[],};},created: function(){// 获取轮播图this.$axios.get("http://api.luffycity.cn:8000/home/banner/").then(res &#61;> {this.banner_list &#61; res.data}).catch(error &#61;> {console.log(error);});}}
script><style scoped>
.banner img{width: 100%;
}
style>
前端引入登陆页面的组件代码并补充路由地址
Login.vue&#xff0c;代码&#xff1a;
<template><div class&#61;"login box"><img src&#61;"https://www.luffycity.com/static/img/Loginbg.3377d0c.jpg" alt&#61;""><div class&#61;"login"><div class&#61;"login-title"><img src&#61;"https://www.luffycity.com/static/img/Logotitle.1ba5466.png" alt&#61;""><p>帮助有志向的年轻人通过努力学习获得体面的工作和生活!p>div><div class&#61;"login_box"><div class&#61;"title"><span &#64;click&#61;"login_type&#61;1" :class&#61;"login_type&#61;&#61;1?&#39;current&#39;:&#39;&#39;">密码登录span><span &#64;click&#61;"login_type&#61;2" :class&#61;"login_type&#61;&#61;2?&#39;current&#39;:&#39;&#39;">短信登录span>div><div class&#61;"inp" :class&#61;"login_type&#61;&#61;1?&#39;show&#39;:&#39;&#39;"><input v-model &#61; &#39;username&#39; type&#61;"text" placeholder&#61;"用户名 / 手机号码" class&#61;"user"><input v-model &#61; &#39;password&#39; type&#61;"password" name&#61;"" class&#61;"pwd" placeholder&#61;"密码"><div id&#61;"geetest1" title&#61;"验证码">div><div class&#61;"rember"><p><input type&#61;"checkbox" class&#61;"no" name&#61;"a">input><span>记住密码span>p><p>忘记密码p>div><button class&#61;"login_btn">登录button><p class&#61;"go_login" >没有账号 <span>立即注册span>p>div><div class&#61;"inp" :class&#61;"login_type&#61;&#61;2?&#39;show&#39;:&#39;&#39;"><input v-model &#61; &#39;username&#39; type&#61;"text" placeholder&#61;"手机号码" class&#61;"user"><input v-model &#61; &#39;password&#39; type&#61;"password" name&#61;"" class&#61;"pwd" placeholder&#61;"短信验证码"><div class&#61;"rember"><p><input type&#61;"checkbox" class&#61;"no" name&#61;"a">input><span>记住密码span>p><p>忘记密码p>div><button class&#61;"login_btn">登录button><p class&#61;"go_login" >没有账号 <span>立即注册span>p>div>div>div>div>
template><script>export default{name:"Login",data(){return {login_type:2,username:"",password:"",}},components:{}}
script><style scoped>
.box{width: 100%;position: relative;}
.box img{width: 100%;
}
.box .login {position: absolute;width: 500px;height: 400px;top: 50%;left: 50%;margin-left: -250px;margin-top: -300px;
}
.login .login-title{width: 100%;text-align: center;
}
.login-title img{width: 190px;height: auto;
}
.login-title p{font-family: PingFangSC-Regular;font-size: 18px;color: #fff;letter-spacing: .29px;padding-top: 10px;padding-bottom: 50px;
}
.login_box{width: 400px;height: auto;background: #fff;box-shadow: 0 2px 4px 0 rgba(0,0,0,.5);border-radius: 4px;margin: 0 auto;padding-bottom: 40px;
}
.login_box .title{font-size: 20px;color: #9b9b9b;letter-spacing: .32px;border-bottom: 1px solid #e6e6e6;display: flex;justify-content: space-around;padding: 50px 60px 0 60px;margin-bottom: 20px;cursor: pointer;
}
.login_box .title .current{color: #4a4a4a;border-bottom: 2px solid #84cc39;
}.inp{width: 350px;margin: 0 auto;display: none;
}
.show{display: block;
}
.inp input{border: 0;outline: 0;width: 100%;height: 45px;border-radius: 4px;border: 1px solid #d9d9d9;text-indent: 20px;font-size: 14px;background: #fff !important;
}
.inp input.user{margin-bottom: 16px;
}
.inp .rember{display: flex;justify-content: space-between;align-items: center;position: relative;margin-top: 10px;
}
.inp .rember p:first-of-type{font-size: 12px;color: #4a4a4a;letter-spacing: .19px;margin-left: 22px;display: -ms-flexbox;display: flex;-ms-flex-align: center;align-items: center;/*position: relative;*/
}
.inp .rember p:nth-of-type(2){font-size: 14px;color: #9b9b9b;letter-spacing: .19px;cursor: pointer;
}.inp .rember input{outline: 0;width: 30px;height: 45px;border-radius: 4px;border: 1px solid #d9d9d9;text-indent: 20px;font-size: 14px;background: #fff !important;
}.inp .rember p span{display: inline-block;font-size: 12px;width: 100px;/*position: absolute;*/
/*left: 20px;*/}
#geetest{margin-top: 20px;
}
.login_btn{width: 100%;height: 45px;background: #84cc39;border-radius: 5px;font-size: 16px;color: #fff;letter-spacing: .26px;margin-top: 30px;
}
.inp .go_login{text-align: center;font-size: 14px;color: #9b9b9b;letter-spacing: .26px;padding-top: 20px;
}
.inp .go_login span{color: #84cc39;cursor: pointer;
}
style>
在routes/index.js中&#xff0c;添加路由
import Vue from "vue"
import Router from "vue-router"// 导入需要注册路由的组件
import Home from "../components/Home"
import Login from "../components/Login"
Vue.use(Router);// 配置路由列表
export default new Router({mode:"history",routes:[// 路由列表{name:"Home",path: "/home",component:Home,},{name:"Home",path: "/",component:Home,},{name:"Login",path: "/login",component:Login,}]
})
修复关于前端无法正常显示图片的问题
1.在settings中设置 MEDIA_URL:
# 项目中存储上传文件的根目录[暂时配置]&#xff0c;注意&#xff0c;static目录需要手动创建否则上传文件时报错
MEDIA_ROOT&#61;os.path.join(BASE_DIR,"luffy/static")# 设置访问上传文件的url地址前缀
MEDIA_URL &#61; "/media/"
此时 MEDIA_URL &#61; "/media/" 中meida 代表着MEDIA_ROOT中代表的路径
2.在视图函数中提供完整的域名地址
from django.db.models import Q
from rest_framework.views import APIView
from rest_framework.response import Responsefrom luffy.apps.home.models import BannerInfoHOST &#61; "http://api.luffycity.cn:8000"
class BannerInfoAPIView(APIView):"""轮播图列表"""def get(self,request):# 获取数据banners &#61; BannerInfo.objects.filter(Q(is_show&#61;True) & Q(is_delete&#61;False)).order_by("-orders")# 调整banners的images字段# 序列化data &#61; []for item in banners:data.append({# 拼接图片的url地址"image": HOST &#43; item.image.url,"link":item.link,"orders":item.orders,})return Response(data)
3.在主urls 设置路由
from django.conf import settings
from django.views.static import serveurlpatterns &#61; [re_path(r&#39;^media/(?P