GVKun编程网logo

在admin中以内联形式限制select中的外键选择

8

如果您对在admin中以内联形式限制select中的外键选择感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于在admin中以内联形式限制select中的外键选择的详细内容,并

如果您对在admin中以内联形式限制select中的外键选择感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于在admin中以内联形式限制select中的外键选择的详细内容,并且为您提供关于django后台admin中的raw_id_fields(显示外键详细信息)、electron-admin-element-vue v2.0.0 已经发布、electron12-vite2-vadmin:基于vue3.x+electron中后台桌面管理系统|Electron后台模板、fastadmin下拉选择selectpage组件自定义参数查询的有价值信息。

本文目录一览:

在admin中以内联形式限制select中的外键选择

在admin中以内联形式限制select中的外键选择

该模型的逻辑是:

  • 一个Building有很多Rooms
  • A Room可能在另一个内部Room(例如壁橱-“ self”上的ForeignKey)
  • A Room只能Room位于同一建筑物的另一个内部(这是棘手的部分)

这是我的代码:

#spaces/models.pyfrom django.db import models    class Building(models.Model):    name=models.CharField(max_length=32)    def __unicode__(self):        return self.nameclass Room(models.Model):    number=models.CharField(max_length=8)    building=models.ForeignKey(Building)    inside_room=models.ForeignKey(''self'',blank=True,null=True)    def __unicode__(self):        return self.number

和:

#spaces/admin.pyfrom ex.spaces.models import Building, Roomfrom django.contrib import adminclass RoomAdmin(admin.ModelAdmin):    passclass RoomInline(admin.TabularInline):    model = Room    extra = 2class BuildingAdmin(admin.ModelAdmin):    inlines=[RoomInline]admin.site.register(Building, BuildingAdmin)admin.site.register(Room)

内联将仅显示当前建筑物中的房间(这就是我想要的)。但是,问题在于,对于inside_room下拉菜单,它显示了“房间”表中的所有房间(包括其他建筑物中的房间)。

在的内联中rooms,我需要将inside_room选择限制为rooms当前的选项building(当前正在由主BuildingAdmin窗体更改的建筑记录)。

我既无法找出limit_choices_to在模型中使用的方法,也无法找出如何正确地正确覆盖管理员的内联表单集(我觉得我应该以某种方式创建自定义内联表单,并传递的building_id将主表单设置为自定义内联,然后根据该字段将查询集限制为该字段的选择-但我只是无法将精力集中在如何做上)。

也许这对于管理站点来说太复杂了,但是似乎总会有用…

答案1

小编典典

将请求实例用作obj的临时容器。重写内联方法formfield_for_foreignkey来修改查询集。这至少在Django 1.2.3上有效。

class RoomInline(admin.TabularInline):    model = Room    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):        field = super(RoomInline, self).formfield_for_foreignkey(db_field, request, **kwargs)        if db_field.name == ''inside_room'':            if request._obj_ is not None:                field.queryset = field.queryset.filter(building__exact = request._obj_)              else:                field.queryset = field.queryset.none()        return fieldclass BuildingAdmin(admin.ModelAdmin):    inlines = (RoomInline,)    def get_form(self, request, obj=None, **kwargs):        # just save obj reference for future processing in Inline        request._obj_ = obj        return super(BuildingAdmin, self).get_form(request, obj, **kwargs)

django后台admin中的raw_id_fields(显示外键详细信息)

django后台admin中的raw_id_fields(显示外键详细信息)

在admin后台类中加入raw_id_fields(只适用于外键)后,会显示外键的详细信息

class ArticleAdmin(admin.ModelAdmin): 
 raw_id_fields = ("newspaper",)

electron-admin-element-vue v2.0.0 已经发布

electron-admin-element-vue v2.0.0 已经发布

electron-admin-element-vue v2.0.0 已经发布

此版本更新内容包括:

第一个版本

详情查看:https://gitee.com/lqsong/electron-admin-element-vue/releases/v2.0.0

electron12-vite2-vadmin:基于vue3.x+electron中后台桌面管理系统|Electron后台模板

electron12-vite2-vadmin:基于vue3.x+electron中后台桌面管理系统|Electron后台模板

系统简介

vite2-electron-admin 一套轻量级的中后台系统解决方案。它整合了vite.js + electron12开发实现。使用了最新的前端技术栈,包含了 i18n 国际化语言,动态权限路由,提供了多功能表格/表单业务功能。

技术框架

  • vue3技术:vite.js+vue3.0+vuex4+vue-router@4
  • 跨端框架:electron^12.0.4
  • 打包工具:vue-cli-plugin-electron-builder
  • UI组件库:element-plus (饿了么vue3组件库)
  • 表格拖拽:sortablejs
  • 图表组件:echarts^5.1.1
  • 国际化:vue-i18n^9.1.6
  • 模拟数据:mockjs

项目结构如下

特征

  1. 支持PC及平板自适应布局
  2. 最新前端技术Vite2、Vue3、Electron12、Element Plus、Vue-i18n、Echarts5.x
  3. 支持组件式+指令式两种权限认证方式
  4. 支持中英文/繁体国际化方案
  5. 支持表格拖拽排序、全屏、树形表格等功能
  6. 支持多主题换肤切换

electron-vite-admin 还支持新开多窗口,以如下换肤窗口为例,前面已经有过相关分享文章,这里就不详细介绍。

import { createWin } from ''@/windows/actions''

// 换肤窗口
const handleOpenTheme = () => {
    createWin({
        title: ''主题换肤'',
        route: ''/skin'',
        width: 750,
        height: 480,
    })
}

electron+vite仿mac风格导航栏

image.png

如上图:为了项目UI一致性,顶部导航栏采用了自定义组件实现,风格有些类似mac导航。

<template>
    <WinBar zIndex="1000">
        <template #wbtn>
            <MsgMenu />
            <Lang />
            <atitle="换肤" @click="handleSkinWin"><i></i></a>
            <Setting />
            <atitle="刷新" @click="handleRefresh"><i></i></a>
            <a::title="isAlwaysOnTop ? ''取消置顶'' : ''置顶''" @click="handleAlwaysTop"><i></i></a>
            <Avatar @logout="handleLogout" />
        </template>
    </WinBar>
</template>

至于具体的实现方式,这里不作过多介绍了。之前有过一些相关分享文章。

入口页main.js

/**
 * 渲染进程主入口
 * @author XiaoYan
 */
import { createApp } from ''vue''
import App from ''./App.vue''
import Router from ''./router''
import Store from ''./store''

// 引入公共配置
import gPlugins from ''./plugins''
import { winCfg, loadWin } from ''./windows/actions''

loadWin().then(config => {
    winCfg.window = config
    createApp(App).use(Router).use(Store).use(gPlugins).mount(''#app'')
})

引入公共组件plugin.js

/**
 * 公共组件/插件配置文件
 * @author XiaoYan
 */

// 引入公共样式
import "@/assets/fonts/iconfont.css"
import "@/assets/css/common.scss"

// 引入elementPlus组件库
import ELPlus from "element-plus"

// 引入国际化配置
import VueI18n, { elPlusLang, getLang } from ''./i18n''

// 引入vue3自定义组件
import V3Layer from ''@/components/v3layer''
import V3Scroll from ''@/components/v3scroll''

// 引入公共组件模板
import WinBar from ''@/components/winbar''
import WinBtn from ''@/components/winbar/winbtn.vue''
import MacBtn from ''@/components/winbar/macbtn.vue''
import Icon from ''@/components/Icon''

import Utils from ''@/utils''
import ElUtil from ''./elUtil''

const gPlugins = (app) => {
    app.use(ELPlus, {
        size: ''small'',
        locale: elPlusLang[getLang()]
    })
    app.use(VueI18n)

    app.use(V3Layer)
    app.use(V3Scroll)

    // 注册公共组件
    app.component(''WinBar'', WinBar)
    app.component(''WinBtn'', WinBtn)
    app.component(''MacBtn'', MacBtn)
    app.component(''Icon'', Icon)

    // 注入全局依赖
    app.provide(''utils'', Utils)
    app.provide(''elUtil'', ElUtil)
}

国际化配置 vue-i18n

新建一个i18n.js用来引入国际化语言配置。

image.png

image.png

/**
 * 国际化配置 VueI18n util
 * @author XiaoYan  Q:282310962
 */

import { createI18n } from "vue-i18n"
import Storage from "@/utils/storage"

// 默认值
export const langKey = ''lang''
export const langVal = ''zh-CN''

/* elementPlus国际化配置 */
import enUS from "element-plus/lib/locale/lang/en"
import zhCN from "element-plus/lib/locale/lang/zh-cn"
import zhTW from "element-plus/lib/locale/lang/zh-tw"
export const elPlusLang = {
    ''en-US'': enUS,
    ''zh-CN'': zhCN,
    ''zh-TW'': zhTW,
}

/* 初始化多语言 */
export const $messages = importAllLang()
export const $lang = getLang()
const i18n = createI18n({
    legacy: false,
    locale: $lang,
    messages: $messages
})

/* 获取语言 */
export function getLang() {
    const lang = Storage.get(langKey)
    return lang || langVal
}

/**
 * 持久化存储
 * @param lang 语言类型 zh-CN / zh-TW / en-US
 */
export function setLang(lang, reload = false) {
    if(getLang() !== lang) {
        Storage.set(langKey, lang || '''')
        // 设置全局语言
        // i18n.global.locale.value = lang

        // 重载页面
        if(reload) {
            window.location.reload()
        }
    }
}

/**
 * 自动化导入本地locale目录下语言配置
 */
export function importAllLang() {
    const langModule = {}
    try {
        const localeCtx = require.context(''@/locale'', true, /([a-z]{2})-?([A-Z]{2})?\.js$/)
        localeCtx.keys().map(path => {
            const pathCtx = localeCtx(path)
            if(pathCtx.default) {
                const pathName = path.replace(/(.*\/)*([^.]+).*/ig, ''$2'')
                if(langModule[pathName]) {
                    langModule[pathName] = {
                        ...langModule[pathName], ...pathCtx.default
                    }
                }else {
                    langModule[pathName] = pathCtx.default
                }
            }
        })
    } catch (error) {
        console.log(error)
    }
    return langModule
}

项目模板布局

项目布局分为Auth和Main两个主要模块。

image.png

  • auth模块模板
<template>
    <div>
        <router-view></router-view>
    </div>
</template>

<script>
import { useRoute } from "vue-router"
import useTitle from ''@/hooks/useTitle''

export default {
    components: {},
    setup() {
        const route = useRoute()

        // 设置标题
        useTitle(route)
    }
}
</script>
  • main模块模板
<template>
    <div:>
        <div v-if="!route.meta.isNewin">
            <!-- 顶部导航 -->
            <div>
                <TopNav />
            </div>
            
            <div>
                <!-- 侧边栏 -->
                <div v-show="rootRouteEnable">
                    <SideMenu :routes="mainRoutes" :rootRoute="rootRoute" />
                </div>

                <!-- 中间栏 -->
                <div:>
                    <RouteMenu 
                        :routes="getAllRoutes" 
                        :rootRoute="rootRoute" 
                        :defaultActive="defaultActive" 
                        :rootRouteEnable="rootRouteEnable" 
                    />
                </div>

                <!-- //右边栏 -->
                <div>
                    <!-- 面包屑 -->
                    <BreadCrumb />
                    
                    <v3-scroll autohide>
                        <div>
                            <permission :roles="route.meta.roles">
                                <template #tooltips>
                                    <Forbidden />
                                </template>
                                <router-view></router-view>
                            </permission>
                        </div>
                    </v3-scroll>
                </div>
            </div>
        </div>
        <router-view v-else></router-view>
    </div>
</template>

图表Hook

为了简化图表调用,封装一个图表hooks。使用到了element-resize-detector来监测dom尺寸变化。

import { onMounted, onBeforeUnmount, ref } from "vue"
import * as echarts from "echarts"
import elementResizeDetectorMaker from "element-resize-detector"
import utils from "@/utils"

export default function useChart(refs, options) {
    let chartInst
    let chartRef = ref(null)
    let erd = elementResizeDetectorMaker()

    const handleResize = utils.debounce(() => {
        chartInst.resize()
    }, 100)

    onMounted(() => {
        if(refs.value) {
            chartInst = echarts.init(refs.value)
            chartInst.setOption(options)
            chartRef.value = chartInst
        }
        erd.listenTo(refs.value, handleResize)
    })

    onBeforeUnmount(() => {
        chartInst.dispose()
        erd.removeListener(refs.value, handleResize)
    })

    return chartRef
}

这样每次调用的时候,只需传入图表dom元素和图表数据即可快速生成一个图表。

Okey,运用electron+vite.js跨端开发后台管理系统暂时分享到这里。

最后附上Electron+Vue3桌面端仿都有短视频+直播
https://segmentfault.com/a/1190000039725671

fastadmin下拉选择selectpage组件自定义参数查询

fastadmin下拉选择selectpage组件自定义参数查询

1.定义查询过滤条件,查询指定数据用于选择
(1)定义data-params单种类条件

data-params=’{“custom[type_pid]”:“0”}’
(2)定义data-params查询判断语法条件

data-params=’{“custom[type_pid][0]”:“not in”,“custom[type_pid][1]”:“0”}’
(3)定义非默认主键值

data-primary-key=“type_id”
完整示例:

关于在admin中以内联形式限制select中的外键选择的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于django后台admin中的raw_id_fields(显示外键详细信息)、electron-admin-element-vue v2.0.0 已经发布、electron12-vite2-vadmin:基于vue3.x+electron中后台桌面管理系统|Electron后台模板、fastadmin下拉选择selectpage组件自定义参数查询等相关内容,可以在本站寻找。

本文标签: