Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Django REST framework+Vue 打造生鲜超市(三)

Django REST framework+Vue 打造生鲜超市(三)

作者头像
zhang_derek
发布于 2018-04-11 03:54:59
发布于 2018-04-11 03:54:59
1.7K00
代码可运行
举报
文章被收录于专栏:有趣的django有趣的django
运行总次数:0
代码可运行

四、xadmin后台管理

4.1.xadmin添加富文本插件

(1)xadmin/plugins文件夹下新建文件ueditor.py

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# xadmin/plugins/ueditor.py

import xadmin
from xadmin.views import BaseAdminPlugin, CreateAdminView, ModelFormAdminView, UpdateAdminView
from DjangoUeditor.models import UEditorField
from DjangoUeditor.widgets import UEditorWidget
from django.conf import settings



class XadminUEditorWidget(UEditorWidget):
    def __init__(self, **kwargs):
        self.ueditor_options = kwargs
        self.Media.js = None
        super(XadminUEditorWidget,self).__init__(kwargs)


class UeditorPlugin(BaseAdminPlugin):

    def get_field_style(self, attrs, db_field, style, **kwargs):
        if style == 'ueditor':
            if isinstance(db_field, UEditorField):
                widget = db_field.formfield().widget
                param = {}
                param.update(widget.ueditor_settings)
                param.update(widget.attrs)
                return {'widget':XadminUEditorWidget(**param)}
        return attrs

    def block_extrahead(self, context, nodes):
        js  = '<script type="text/javascript" src="%s"></script>' %(settings.STATIC_URL + "ueditor/ueditor.config.js")
        js += '<script type="text/javascript" src="%s"></script>' %(settings.STATIC_URL + "ueditor/ueditor.all.min.js")
        nodes.append(js)

xadmin.site.register_plugin(UeditorPlugin, UpdateAdminView)
xadmin.site.register_plugin(UeditorPlugin, CreateAdminView)

(2)把插件添加到__init__.py里面

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# xadmin/plugins/__init__.py

PLUGINS = (
    'ueditor',
)

4.2.url配置

配置xadmin和ueditor的路由

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# MxShop/urls.py

import xadmin

from django.urls import path,include

urlpatterns = [
    path('xadmin/', xadmin.site.urls),
    path('ueditor/', include('DjangoUeditor.urls')),
]

4.3.注册app到xadmin后台

四个app下面都新建文件adminx.py,然后分别注册到后台

(1)users/adminx.py

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# users/adminx.py
__author__ = 'derek'

import xadmin
from xadmin import views
from .models import VerifyCode


class BaseSetting(object):
    #添加主题功能
    enable_themes = True
    use_bootswatch = True


class GlobalSettings(object):
    #全局配置,后台管理标题和页脚
    site_title = "仙剑奇侠传"
    site_footer = "http://www.cnblogs.com/derek1184405959/"
    #菜单收缩
    menu_style = "accordion"


class VerifyCodeAdmin(object):
    list_display = ['code', 'mobile', "add_time"]


xadmin.site.register(VerifyCode, VerifyCodeAdmin)
xadmin.site.register(views.BaseAdminView, BaseSetting)
xadmin.site.register(views.CommAdminView, GlobalSettings)

修改app名字为中文

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# users/apps.py

from django.apps import AppConfig


class UsersConfig(AppConfig):
    name = 'users'
    #app名字后台显示中文
    verbose_name = "用户管理"

还需要__init__.py中修改默认配置才生效

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# users/__init__.py

default_app_config = 'users.apps.UsersConfig'

其它三个app一样的操作

(2)goods/adminx.py

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# goods/adminx.py

import xadmin
from .models import Goods, GoodsCategory, GoodsImage, GoodsCategoryBrand, Banner, HotSearchWords
from .models import IndexAd


class GoodsAdmin(object):
    #显示的列
    list_display = ["name", "click_num", "sold_num", "fav_num", "goods_num", "market_price",
                    "shop_price", "goods_brief", "goods_desc", "is_new", "is_hot", "add_time"]
    #可以搜索的字段
    search_fields = ['name', ]
    #列表页可以直接编辑的
    list_editable = ["is_hot", ]
    #过滤器
    list_filter = ["name", "click_num", "sold_num", "fav_num", "goods_num", "market_price",
                   "shop_price", "is_new", "is_hot", "add_time", "category__name"]
    #富文本编辑器
    style_fields = {"goods_desc": "ueditor"}

    #在添加商品的时候可以添加商品图片
    class GoodsImagesInline(object):
        model = GoodsImage
        exclude = ["add_time"]
        extra = 1
        style = 'tab'

    inlines = [GoodsImagesInline]


class GoodsCategoryAdmin(object):
    list_display = ["name", "category_type", "parent_category", "add_time"]
    list_filter = ["category_type", "parent_category", "name"]
    search_fields = ['name', ]


class GoodsBrandAdmin(object):
    list_display = ["category", "image", "name", "desc"]

    def get_context(self):
        context = super(GoodsBrandAdmin, self).get_context()
        if 'form' in context:
            context['form'].fields['category'].queryset = GoodsCategory.objects.filter(category_type=1)
        return context


class BannerGoodsAdmin(object):
    list_display = ["goods", "image", "index"]


class HotSearchAdmin(object):
    list_display = ["keywords", "index", "add_time"]


class IndexAdAdmin(object):
    list_display = ["category", "goods"]


xadmin.site.register(Goods, GoodsAdmin)
xadmin.site.register(GoodsCategory, GoodsCategoryAdmin)
xadmin.site.register(Banner, BannerGoodsAdmin)
xadmin.site.register(GoodsCategoryBrand, GoodsBrandAdmin)

xadmin.site.register(HotSearchWords, HotSearchAdmin)
xadmin.site.register(IndexAd, IndexAdAdmin)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# goods/apps.py

from django.apps import AppConfig

class GoodsConfig(AppConfig):
    name = 'goods'
    verbose_name = '商品管理'
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# good/__init__.py

default_app_config = 'goods.apps.GoodsConfig'

(3)trade/adminx.py

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# trade/adminx.py
__author__ = 'derek'

import xadmin
from .models import ShoppingCart, OrderInfo, OrderGoods


class ShoppingCartAdmin(object):
    list_display = ["user", "goods", "nums", ]


class OrderInfoAdmin(object):
    list_display = ["user", "order_sn",  "trade_no", "pay_status", "post_script", "order_mount",
                    "order_mount", "pay_time", "add_time"]

    class OrderGoodsInline(object):
        model = OrderGoods
        exclude = ['add_time', ]
        extra = 1
        style = 'tab'

    inlines = [OrderGoodsInline, ]


xadmin.site.register(ShoppingCart, ShoppingCartAdmin)
xadmin.site.register(OrderInfo, OrderInfoAdmin)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# trade/apps.py

from django.apps import AppConfig


class TradeConfig(AppConfig):
    name = 'trade'
    verbose_name = '交易管理'
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# trade/__init__.py

default_app_config = 'trade.apps.TradeConfig'

(4)user_operation/adminx.py

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# user_operation/adminx.py
__author__ = 'derek'


import xadmin
from .models import UserFav, UserLeavingMessage, UserAddress


class UserFavAdmin(object):
    list_display = ['user', 'goods', "add_time"]


class UserLeavingMessageAdmin(object):
    list_display = ['user', 'message_type', "message", "add_time"]


class UserAddressAdmin(object):
    list_display = ["signer_name", "signer_mobile", "district", "address"]

xadmin.site.register(UserFav, UserFavAdmin)
xadmin.site.register(UserAddress, UserAddressAdmin)
xadmin.site.register(UserLeavingMessage, UserLeavingMessageAdmin)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# user_operation/apps.py

from django.apps import AppConfig


class UserOperationConfig(AppConfig):
    name = 'user_operation'
    verbose_name = '操作管理'
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# user_operation/__init__.py

default_app_config = 'user_operation.apps.UserOperationConfig'

(5)生成数据库表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
python manage.py makemigrations

python manage.py migrate

4.4.导入商品类别数据

由于分类和商品很多,就写个脚本导入数据

单独使用django的model,批量导入数据

  • db_tools下新建文件夹data,然后把前端的json文件(category_data和product_data)拷贝到里面
  •  把brands和goods图片拷贝到media目录下

db_tools下新建文件 import_category_data.py

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# db_tools/data/import_category_data.py

#独立使用django的model
import sys
import os

#获取当前文件的路径(运行脚本)
pwd = os.path.dirname(os.path.realpath(__file__))
#获取项目的跟目录
sys.path.append(pwd+"../")
#要想单独使用django的model,必须指定一个环境变量,会去settings配置找
#参照manage.py里面就知道为什么这样设置了
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MxShop.settings")

import django
django.setup()

from goods.models import GoodsCategory

from db_tools.data.category_data import row_data

#一级类
for lev1_cat in row_data:
    lev1_intance = GoodsCategory()
    lev1_intance.code = lev1_cat["code"]
    lev1_intance.name = lev1_cat["name"]
    lev1_intance.category_type = 1
    #保存到数据库
    lev1_intance.save()
#二级类
    for lev2_cat in lev1_cat["sub_categorys"]:
        lev2_intance = GoodsCategory()
        lev2_intance.code = lev2_cat["code"]
        lev2_intance.name = lev2_cat["name"]
        lev2_intance.category_type = 2
        lev2_intance.parent_category = lev1_intance
        lev2_intance.save()
#三级类
        for lev3_cat in lev2_cat["sub_categorys"]:
            lev3_intance = GoodsCategory()
            lev3_intance.code = lev3_cat["code"]
            lev3_intance.name = lev3_cat["name"]
            lev3_intance.category_type = 3
            lev3_intance.parent_category = lev2_intance
            lev3_intance.save()

然后运行脚本 import_category_data.py  数据就可以保存到数据库了

4.5.导入商品

 在data目录下新建import_goods_data.py

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import sys
import os

pwd = os.path.dirname(os.path.realpath(__file__))
sys.path.append(pwd+"../")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MxShop.settings")

import django
django.setup()

from goods.models import Goods, GoodsCategory, GoodsImage

from db_tools.data.product_data import row_data

for goods_detail in row_data:
    goods = Goods()
    goods.name = goods_detail["name"]
    #前端中是“¥232”,数据库中是float类型,所以要替换掉
    goods.market_price = float(int(goods_detail["market_price"].replace("¥", "").replace("元", "")))
    goods.shop_price = float(int(goods_detail["sale_price"].replace("¥", "").replace("元", "")))
    goods.goods_brief = goods_detail["desc"] if goods_detail["desc"] is not None else ""
    goods.goods_desc = goods_detail["goods_desc"] if goods_detail["goods_desc"] is not None else ""
    # 取第一张作为封面图
    goods.goods_front_image = goods_detail["images"][0] if goods_detail["images"] else ""
    #取最后一个
    category_name = goods_detail["categorys"][-1]
    # 取出当前子类对应的GoodsCategory对象,filter没有匹配的会返回空数组,不会抛异常。
    category = GoodsCategory.objects.filter(name=category_name)
    if category:
        goods.category = category[0]
    goods.save()

    for goods_image in goods_detail["images"]:
        goods_image_instance = GoodsImage()
        goods_image_instance.image = goods_image
        goods_image_instance.goods = goods
        goods_image_instance.save()

然后运行,把商品生产到数据库中

配置media路径

settings中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 设置上传文件的路径
MEDIA_URL="/media/"
MEDIA_ROOT=os.path.join(BASE_DIR,"media")

urls.py

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# MxShop/urls.py
__author__ = 'derek'

from django.urls import path,include
import xadmin
from django.views.static import serve
from MxShop.settings import MEDIA_ROOT

urlpatterns = [
    path('xadmin/', xadmin.site.urls),
    path('ueditor/',include('DjangoUeditor.urls' )),
    #文件
    path('media/<path:path>',serve,{'document_root':MEDIA_ROOT}),
]

 目录结构

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-04-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
SpringBoot3.x日志生产最佳实践原来是这样!
SpringBoot对日志的配置和加载进行了封装,让我们可以很方便地使用一些日志框架,只需要定义对应日志框架的配置文件,如LogBack、Log4j、Log4j2等,代码内部便可以直接使用。
JavaEdge
2023/08/15
2.5K0
SpringBoot3.x日志生产最佳实践原来是这样!
SpringBoot 系列-日志详解
默认情况下,如果使用 “starters”,则使用 Logback 进行日志记录。还包括适当的 Logback 路由,以确保使用 Java Util 日志记录、Commons 日志记录、Log4J 或 SLF4J 的依赖库都能正常工作。
安徽开发者圈
2020/03/02
1.9K0
SpringBoot日志源码解析:日志监听器的执行
LoggingApplicationListener 的主要作用是配置LoggingSystem, 如果 环境 包含 loggingconfig 属性,LoggingApplicationListener 将用于引导 日志记录系统,否则使用默认配置。
愿天堂没有BUG
2022/10/28
1K0
SpringBoot日志源码解析:日志监听器的执行
日志框架Log4j的学习小记
Java项目的框架基本就是slf4j,slf4j提供了一套规范,也就是门面,而至于后边是如何实现的只要按照人家定义的接口去做就行了。常见的日志框架又springboot自带的logback,还有异步的日志框架log4j,当然还有一些大佬自己做日志框架的。这里作者大概的看了一下日志框架的代码。稍微讲解一下日志框架是怎么做的。
写一点笔记
2022/08/11
3070
日志框架Log4j的学习小记
聊聊springboot的logging.group
org/springframework/boot/actuate/logging/LoggersEndpoint.java
code4it
2023/12/02
1990
从源码分析 SpringBoot 的 LoggingSystem → 它是如何绑定日志组件的
SpringBoot2.7 霸王硬上弓 Logback1.3 → 不甜但解渴 实现了 spring-boot 2.x.x 与 logback 1.3.x 的集成,分两步
青石路
2024/08/23
2540
从源码分析 SpringBoot 的 LoggingSystem → 它是如何绑定日志组件的
聊聊springboot的LogbackLoggingSystem
org/springframework/boot/logging/LoggingSystem.java
code4it
2023/11/02
2900
动态设置 log4j2 日志的级别不能落
上篇[ SpringBoot 动态设置 logback 日志的级别 ] 说了 logback 动态设置日志级别。这篇来说下 log4j2 日志框架结合 SpringBoot 动态设置日志级别。因为 log4j2 日志框架也有非常多的公司采用,毕竟 logback 和 log4j2 是现在用的最多的两个日志框架。都不能落对吧。
BUG弄潮儿
2021/05/17
2K0
动态设置 log4j2 日志的级别不能落
springboot中log加载流程
springboot容器启动的时候, 会在不同的阶段发送Event事件. 在LoggingApplicationListener中代码如下:
eeaters
2024/11/11
1671
springboot中log加载流程
聊聊springboot的LogbackLoggingSystem
org/springframework/boot/logging/LoggingSystem.java
code4it
2023/11/03
2150
聊聊springboot的LogbackLoggingSystem
集成动态日志,“消灭”logback-spring.xml
动态调整线上日志级别是一个非常常见的场景,借助apollo这种配置中心组件非常容易实现。作为apollo的官方技术支持,博主经常在技术群看到有使用者询问apollo是否可以托管logback的配置文件,毕竟有了配置中心后,消灭所有的本地配置全部交给apollo管理是我们的最终目标。可是,apollo不具备直接托管logback-spring.xml配置文件能力,但是,我们可以基于spring和logback的装载机制,完全取缔logback-spring.xml配置,以apollo中的配置驱动。而且,改造后,大大提高了日志系统的灵活性和可扩展性。
用户5546570
2020/12/09
1.5K0
实战:如何优雅地扩展Log4j配置?
Log4j 日志框架我们经常会使用到,最近,我就遇到了一个与日志配置相关的问题。简单来说,就是在原来日志配置的基础上,指定类的日志打印到指定的日志文件中。
杨同学technotes
2022/12/01
6310
springboot 默认日志配置源码
版本 2.2.x 日志系统初始化流程 应用启动时,ApplicationStartingEvent触发,屏蔽所有日志 ApplicationEnvironmentPreparedEvent触发,清空所有日志配置,重新初始化日志系统 配置变更,EnvironmentChangeEvent触发,重新设置日志级别 源码 org.springframework.cloud.bootstrap.LoggingSystemShutdownListener public class LoggingSystemShutdo
路过君
2020/09/07
1K0
日志级别动态调整——小工具解决大问题
背景 随着外卖业务的快速发展,业务复杂度不断增加,线上系统环境有任何细小波动,对整个外卖业务都可能产生巨大的影响,甚至形成灾难性的雪崩效应,造成巨大的经济损失。每一次客诉、系统抖动等都是对技术人员的重大考验,我们必须立即响应,快速解决问题。 如何提高排查问题的效率呢?最有效的方式是通过分析系统日志。如果系统日志全面,会为我们排查解决线上问题带来绝大的帮助,但是要想保证系统日志全面,就必须打印出所有的系统或业务日志。这样就会带来另一个问题,那就是日志量的暴涨,过多的日志除了能够帮助我们解决问题外,同时会直接造
美团技术团队
2018/03/12
2.5K1
日志级别动态调整——小工具解决大问题
Spring Boot 2动态修改日志级别
作为程序猿,定位问题是我们的日常工作,而日志是我们定位问题非常重要的依据。传统方式定位问题时,往往是如下步骤:
乱敲代码
2019/06/03
1.5K0
springboot超级详细的日志配置(基于logback)
  java web 下有好几种日志框架,比如:logback,log4j,log4j2(slj4f 并不是一种日志框架,它相当于定义了规范,实现了这个规范的日志框架就能够用 slj4f 调用)。其中性能最高的应该使 logback 了,而且 springboot 默认使用的也是 logback 日志,所以本篇将会详细的讲解 logback 的日志配置方案。
用户2038589
2019/06/13
26.3K0
SpringBoot 用的 spring-jcl 打印日志,与 LoggingSystem 有鸡毛关系?
从源码分析 SpringBoot 的 LoggingSystem → 它是如何绑定日志组件的 从源码的角度讲述了 Spring Boot 的 LoggingSystem 与日志组件的绑定,默认情况下绑定的是 Logback;但当我们具体去看 Spring Boot 的日志打印,却发现用的是 spring-jcl ,通过它适配了 slf4j,真正的日志打印还得依赖具体的日志组件,默认情况下使用的是 logback;那这么说来,Spring Boot 的日志打印与 Spring Boot 的 LoggingSystem 貌似没关系呀?
青石路
2024/08/24
1430
SpringBoot 用的 spring-jcl 打印日志,与 LoggingSystem 有鸡毛关系?
Spring Boot 系列:日志动态配置详解
不知道大家有没有过当线上出现问题的时候,需要某些DEBUG日志,但奈何当前使用时INFO。
用户5546570
2020/10/27
2.1K0
Spring Boot 系列:日志动态配置详解
Spring Boot 2动态修改日志级别
作为程序猿,定位问题是我们的日常工作,而日志是我们定位问题非常重要的依据。传统方式定位问题时,往往是如下步骤:
张乘辉
2019/06/14
1.3K0
Spring Boot 2动态修改日志级别
Java日志体系(log4j2)
1 log4j2 1.1 简介 log4j2,一个日志的实现框架,是log4j的升级版本,于2014年7月正式亮相。与第一代log4j不同,log4j2完全重写了log4j的日志实现,并不是在原有基础
贾博岩
2018/05/11
3K0
推荐阅读
相关推荐
SpringBoot3.x日志生产最佳实践原来是这样!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验