导航栏前后端
只做了轮播图前后端,操作还是不熟练的,因此还要对导航栏的前后端来做一个阐述,这样印象、理解会更加深刻。
导航栏后端
做一个后端api,我们需要定义数据模型models存储数据、创建视图view筛选操作数据、创建序列化器serializer将数据序列化方便前端获取、声明urls为前端获取数据时提供方向,额外的工作是将定义好的模型注册到xadmin中,方便管理数据。
定义模型models.py
class Nav(BaseModel):
"""导航菜单模型"""
POSITION_OPTION = (
(1, "顶部导航"),
(2, "脚部导航")
)
title = models.CharField(max_length=500, verbose_name="导航标题")
link = models.CharField(max_length=500, verbose_name="导航链接")
position = models.IntegerField(choices=POSITION_OPTION, default=1, verbose_name="导航位置")
is_site = models.BooleanField(default=False, verbose_name="是否是外转地址")
class Meta:
db_table = "ly_nav"
verbose_name = "导航菜单"
verbose_name_plural = verbose_name
def __str__(self):
return self.title
值得注意的是,我们将那些好多表都要用的字段提取到utils.models.BaseModel中,需要用到这些字段的模型继承这个类便可。这是符合工程要求的,减小代码的耦合度,提高代码的复用性。
创建试图view.py
导航栏分为头部导航和脚部导航,前面的模型中我们也是定义了一个导航位置信息,所以这里面可以用filter来选取是头部导航还是脚部导航
from .models import Nav
from .serializers import NavModelSerializer
class HeaderNavListAPIView(ListAPIView):
"""导航菜单"""
#query相当于数据库里面的select操作
queryset = Nav.objects.filter(is_show=True, is_delete=False, position=1).order_by("-orders","-id")[:constants.HEADER_NAV_LENGTH]
#序列化器,只显示序列化器中fields字段
serializer_class = NavModelSerializer
class FooterNavListAPIView(ListAPIView):
"""脚部导航菜单"""
#query相当于数据库里面的select操作
queryset = Nav.objects.filter(is_show=True, is_delete=False, position=2).order_by("-orders","-id")[:constants.FOOTER_NAV_LENGTH]
#序列化器,只显示序列化器中fields字段
serializer_class = NavModelSerializer
创建序列化器serializer.py
我们只需要一个序列化器,因为前面的视图已经把数据过滤好了,只需要序列化视图过滤好的数据就行
class NavModelSerializer(serializers.ModelSerializer):
class Meta:
model = Nav
fields = ['title', 'link', 'is_site']
路由注册urls.py
path(r'nav/header/', views.HeaderNavListAPIView.as_view()),
path(r'nav/footer/', views.FooterNavListAPIView.as_view()),
注册好指定的路由便可以访问这个api获取数据了
在adminx.py中注册模型
from .models import Nav
class NavModelAdmin(object):
list_display=["title","link","is_show","is_site","position"]
xadmin.site.register(Nav, NavModelAdmin)
导航栏前端
前端页面步骤为:在vue组件中的script部分使用ajax请求获取数据,并返回给template;template使用vue语法,v-for、v-if等方法对数据进行填充渲染
script
<script>
export default {
name: "Header",
data(){
return{
nav_list: []
}
},
created() {
this.get_nav();
},
methods:{
get_nav(){
this.$axios.get(`${this.$settings.HOST}/nav/header`, {}).then(response=>{
this.nav_list = response.data;
}).catch(error=>{
console.log(error.response);
})
}
}
}
</script>
template
就不全贴了,只贴关键的部分
<ul class="nav full-left">
<li :key="key" v-for="nav,key in nav_list">
<span v-if="nav.is_site"><a :href="nav.link">{{nav.title}}</a></span>
<span v-else><router-link :to="nav.link">{{nav.title}}</router-link></span>
</li>
</ul>
这是头部导航栏的部分,脚部导航栏一样的道理,下面自己去实现