分支机构的项目管理,基于Django
This commit is contained in:
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
3816
.idea/CopilotChatHistory.xml
generated
Normal file
3816
.idea/CopilotChatHistory.xml
generated
Normal file
File diff suppressed because one or more lines are too long
8
.idea/fzjg-activation.iml
generated
Normal file
8
.idea/fzjg-activation.iml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
27
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
27
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyBroadExceptionInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredErrors">
|
||||
<list>
|
||||
<option value="E722" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredErrors">
|
||||
<list>
|
||||
<option value="N802" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredIdentifiers">
|
||||
<list>
|
||||
<option value="news.models.News.*" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
10
.idea/misc.xml
generated
Normal file
10
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.11" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11" project-jdk-type="Python SDK" />
|
||||
<component name="PyCharmProfessionalAdvertiser">
|
||||
<option name="shown" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/fzjg-activation.iml" filepath="$PROJECT_DIR$/.idea/fzjg-activation.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
66
count_lines.py
Normal file
66
count_lines.py
Normal file
@@ -0,0 +1,66 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
def count_lines_in_file(file_path):
|
||||
"""统计单个文件的行数"""
|
||||
try:
|
||||
with open(file_path, 'r', encoding='utf-8') as file:
|
||||
return sum(1 for _ in file)
|
||||
except UnicodeDecodeError:
|
||||
try:
|
||||
with open(file_path, 'r', encoding='gbk') as file:
|
||||
return sum(1 for _ in file)
|
||||
except UnicodeDecodeError:
|
||||
print(f"无法解码文件: {file_path}")
|
||||
return 0
|
||||
except Exception as e:
|
||||
print(f"读取文件 {file_path} 时出错: {e}")
|
||||
return 0
|
||||
|
||||
def count_lines_in_directory(directory, extensions):
|
||||
"""统计目录中特定扩展名文件的总行数"""
|
||||
total_lines = 0
|
||||
file_count = 0
|
||||
|
||||
for root, dirs, files in os.walk(directory):
|
||||
# 跳过__pycache__目录
|
||||
if '__pycache__' in root:
|
||||
continue
|
||||
|
||||
for file in files:
|
||||
if any(file.endswith(ext) for ext in extensions):
|
||||
file_path = os.path.join(root, file)
|
||||
lines = count_lines_in_file(file_path)
|
||||
total_lines += lines
|
||||
file_count += 1
|
||||
print(f"{file_path}: {lines} 行")
|
||||
|
||||
return total_lines, file_count
|
||||
|
||||
def main():
|
||||
project_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# 统计Python文件
|
||||
print("=== Python文件行数统计 ===")
|
||||
py_lines, py_files = count_lines_in_directory(project_dir, ['.py'])
|
||||
print(f"\nPython文件总数: {py_files}")
|
||||
print(f"Python文件总行数: {py_lines}")
|
||||
|
||||
# 统计前端文件 (HTML, CSS, JS)
|
||||
print("\n=== 前端文件行数统计 ===")
|
||||
frontend_extensions = ['.html', '.css', '.js']
|
||||
frontend_lines, frontend_files = count_lines_in_directory(project_dir, frontend_extensions)
|
||||
print(f"\n前端文件总数: {frontend_files}")
|
||||
print(f"前端文件总行数: {frontend_lines}")
|
||||
|
||||
# 总计
|
||||
total_files = py_files + frontend_files
|
||||
total_lines = py_lines + frontend_lines
|
||||
print("\n=== 项目总计 ===")
|
||||
print(f"文件总数: {total_files}")
|
||||
print(f"代码总行数: {total_lines}")
|
||||
print(f"Python文件占比: {py_lines/total_lines*100:.2f}%")
|
||||
print(f"前端文件占比: {frontend_lines/total_lines*100:.2f}%")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
BIN
fzjgact/db.sqlite3
Normal file
BIN
fzjgact/db.sqlite3
Normal file
Binary file not shown.
0
fzjgact/fzjgact/__init__.py
Normal file
0
fzjgact/fzjgact/__init__.py
Normal file
BIN
fzjgact/fzjgact/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
fzjgact/fzjgact/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
fzjgact/fzjgact/__pycache__/settings.cpython-311.pyc
Normal file
BIN
fzjgact/fzjgact/__pycache__/settings.cpython-311.pyc
Normal file
Binary file not shown.
BIN
fzjgact/fzjgact/__pycache__/urls.cpython-311.pyc
Normal file
BIN
fzjgact/fzjgact/__pycache__/urls.cpython-311.pyc
Normal file
Binary file not shown.
BIN
fzjgact/fzjgact/__pycache__/wsgi.cpython-311.pyc
Normal file
BIN
fzjgact/fzjgact/__pycache__/wsgi.cpython-311.pyc
Normal file
Binary file not shown.
16
fzjgact/fzjgact/asgi.py
Normal file
16
fzjgact/fzjgact/asgi.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
ASGI config for fzjgact project.
|
||||
|
||||
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'fzjgact.settings')
|
||||
|
||||
application = get_asgi_application()
|
||||
136
fzjgact/fzjgact/settings.py
Normal file
136
fzjgact/fzjgact/settings.py
Normal file
@@ -0,0 +1,136 @@
|
||||
"""
|
||||
Django settings for fzjgact project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 5.0.6.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.0/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/5.0/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 'django-insecure-y_ky#j@s(-ayj+5yo)02&f%w-(flx5p)2sv3yl5j_az4$&c)ih'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ['10.124.107.72', '127.0.0.1', 'localhost']
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
"unfold", # before django.contrib.admin
|
||||
"unfold.contrib.filters", # optional, if special filters are needed
|
||||
"unfold.contrib.forms", # optional, if special form elements are needed
|
||||
"unfold.contrib.inlines", # optional, if special inlines are needed
|
||||
"unfold.contrib.import_export", # optional, if django-import-export package is used
|
||||
"unfold.contrib.guardian", # optional, if django-guardian package is used
|
||||
"unfold.contrib.simple_history", # optional, if django-simple-history package is used
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'huodong',
|
||||
'rest_framework',
|
||||
'django_select2',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'fzjgact.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'fzjgact.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': BASE_DIR / 'db.sqlite3',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/5.0/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'zh-hans'
|
||||
TIME_ZONE = 'Asia/Shanghai'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/5.0/howto/static-files/
|
||||
|
||||
STATIC_URL = 'static/'
|
||||
|
||||
# 媒体文件配置
|
||||
MEDIA_URL = '/media/'
|
||||
MEDIA_ROOT = BASE_DIR / 'media'
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
25
fzjgact/fzjgact/urls.py
Normal file
25
fzjgact/fzjgact/urls.py
Normal file
@@ -0,0 +1,25 @@
|
||||
"""
|
||||
URL configuration for fzjgact project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/5.0/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('', include("huodong.urls")),
|
||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
16
fzjgact/fzjgact/wsgi.py
Normal file
16
fzjgact/fzjgact/wsgi.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
WSGI config for fzjgact project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'fzjgact.settings')
|
||||
|
||||
application = get_wsgi_application()
|
||||
0
fzjgact/huodong/__init__.py
Normal file
0
fzjgact/huodong/__init__.py
Normal file
BIN
fzjgact/huodong/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
fzjgact/huodong/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
fzjgact/huodong/__pycache__/admin.cpython-311.pyc
Normal file
BIN
fzjgact/huodong/__pycache__/admin.cpython-311.pyc
Normal file
Binary file not shown.
BIN
fzjgact/huodong/__pycache__/apps.cpython-311.pyc
Normal file
BIN
fzjgact/huodong/__pycache__/apps.cpython-311.pyc
Normal file
Binary file not shown.
BIN
fzjgact/huodong/__pycache__/models.cpython-311.pyc
Normal file
BIN
fzjgact/huodong/__pycache__/models.cpython-311.pyc
Normal file
Binary file not shown.
BIN
fzjgact/huodong/__pycache__/serializers.cpython-311.pyc
Normal file
BIN
fzjgact/huodong/__pycache__/serializers.cpython-311.pyc
Normal file
Binary file not shown.
BIN
fzjgact/huodong/__pycache__/urls.cpython-311.pyc
Normal file
BIN
fzjgact/huodong/__pycache__/urls.cpython-311.pyc
Normal file
Binary file not shown.
BIN
fzjgact/huodong/__pycache__/views.cpython-311.pyc
Normal file
BIN
fzjgact/huodong/__pycache__/views.cpython-311.pyc
Normal file
Binary file not shown.
194
fzjgact/huodong/admin.py
Normal file
194
fzjgact/huodong/admin.py
Normal file
@@ -0,0 +1,194 @@
|
||||
from django.contrib import admin
|
||||
from django.contrib.admin.actions import delete_selected
|
||||
from django.urls import reverse
|
||||
from django.utils.html import format_html
|
||||
from .models import Branch, EquipmentImage, Drawing, PublicScreen
|
||||
from .models import Activity, Branch, Event, Contact, VideoTerminal
|
||||
from django_select2.forms import Select2Widget
|
||||
from unfold.admin import ModelAdmin
|
||||
from django.contrib.admin import AdminSite
|
||||
from django.contrib.auth.models import User, Group
|
||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||
from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin
|
||||
from django.db.models import Count, Q
|
||||
|
||||
from django.utils.html import format_html
|
||||
from django.urls import reverse
|
||||
from django import forms
|
||||
|
||||
|
||||
# 定义Activity的内联admin类
|
||||
class ActivityInline(admin.TabularInline): # 改为更紧凑的表格形式内联(原StackedInline为堆叠形式)
|
||||
model = Activity
|
||||
extra = 1 # 在Branch表单中默认显示1个额外的Activity表单(可根据需求调整数值)
|
||||
fields = ('name', 'scope', 'start_time', 'end_time') # 限制内联表单显示的字段
|
||||
readonly_fields = ('start_time',) # 可选:将开始时间设为只读字段(避免误修改)
|
||||
# 可选:添加帮助文本提示
|
||||
help_texts = {
|
||||
'name': '请输入活动名称(必填)',
|
||||
'scope': '选择活动范围(内部/外部)'
|
||||
}
|
||||
|
||||
|
||||
admin.site.unregister(User)
|
||||
admin.site.unregister(Group)
|
||||
|
||||
|
||||
@admin.register(User)
|
||||
class UserAdmin(BaseUserAdmin, ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
@admin.register(Group)
|
||||
class GroupAdmin(BaseGroupAdmin, ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
@admin.register(Branch)
|
||||
class BranchAdmin(ModelAdmin):
|
||||
inlines = [ActivityInline]
|
||||
list_display = ('name', 'location', 'category', 'display_mature_status', 'background_color')
|
||||
search_fields = ['name', 'location']
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields': ('name', 'location', 'contact_info', 'description', 'category', 'is_mature', 'background_color')
|
||||
}),
|
||||
)
|
||||
|
||||
def display_mature_status(self, obj):
|
||||
return '💼' if obj.is_mature else '📒'
|
||||
display_mature_status.short_description = '是否成熟'
|
||||
|
||||
def activity_count(self, obj):
|
||||
return obj.activity_set.count()
|
||||
|
||||
activity_count.short_description = '活动数量'
|
||||
|
||||
def get_queryset(self, request):
|
||||
queryset = super().get_queryset(request)
|
||||
queryset = queryset.annotate(
|
||||
inspection_person_count=Count('contact', filter=Q(contact__category='机房/设备间巡检人')))
|
||||
return queryset
|
||||
|
||||
actions = ['set_branches_to_type_b']
|
||||
|
||||
def set_branches_to_type_b(self, request, queryset):
|
||||
queryset.update(category='B型')
|
||||
|
||||
set_branches_to_type_b.short_description = '将选中的分支机构统一改为B型'
|
||||
|
||||
|
||||
# 注册Activity模型(如果需要的话,虽然在这个示例中我们主要关注Branch)
|
||||
@admin.register(Activity)
|
||||
class ActivityAdmin(ModelAdmin):
|
||||
list_display = ('branch', 'scope', 'name', 'start_time', 'end_time')
|
||||
search_fields = ["branch__name"] # 改为关联Branch模型的name字段
|
||||
add_form_template = 'admin/huodong/add_form.html'
|
||||
|
||||
autocomplete_fields = ['branch']
|
||||
|
||||
|
||||
@admin.register(Event)
|
||||
class EventAdmin(ModelAdmin):
|
||||
list_display = ('name', 'start_time', 'end_time', 'description')
|
||||
filter_horizontal = ('branches',)
|
||||
|
||||
|
||||
class ContactAdminForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Contact
|
||||
fields = '__all__'
|
||||
widgets = {
|
||||
# 使用复选框实现多选
|
||||
'category': forms.CheckboxSelectMultiple(choices=Contact.CATEGORY_CHOICES)
|
||||
}
|
||||
|
||||
|
||||
class EquipmentImageAdmin(admin.ModelAdmin):
|
||||
def bulk_delete_selected(self, request, queryset):
|
||||
count = queryset.count()
|
||||
queryset.delete()
|
||||
self.message_user(request, f'已成功删除{count}条设备图片记录')
|
||||
bulk_delete_selected.short_description = '批量删除选中的设备图片'
|
||||
actions = ['bulk_delete_selected']
|
||||
list_display = ['id', 'branch', 'uploaded_at', 'delete_link']
|
||||
|
||||
def delete_link(self, obj):
|
||||
url = reverse('admin:huodong_equipmentimage_delete', args=[obj.id])
|
||||
return format_html('<a class="deletelink" href="{}">删除</a>', url)
|
||||
delete_link.short_description = '操作'
|
||||
list_filter = ['branch']
|
||||
search_fields = ['branch__name']
|
||||
|
||||
autocomplete_fields = ['branch']
|
||||
|
||||
def get_form(self, request, obj=None, **kwargs):
|
||||
form = super().get_form(request, obj, **kwargs)
|
||||
# 设置默认分支机构为最后一个设备间图片的分支机构
|
||||
try:
|
||||
latest_image = EquipmentImage.objects.latest('uploaded_at')
|
||||
form.base_fields['branch'].initial = latest_image.branch_id
|
||||
except EquipmentImage.DoesNotExist:
|
||||
pass
|
||||
return form
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
super().save_model(request, obj, form, change)
|
||||
# Count images for the current branch
|
||||
count = EquipmentImage.objects.filter(branch=obj.branch).count()
|
||||
self.message_user(request, f"【{obj.branch.name}】已经有{count}张设备间图片。")
|
||||
|
||||
admin.site.register(EquipmentImage, EquipmentImageAdmin)
|
||||
|
||||
class DrawingAdmin(admin.ModelAdmin):
|
||||
def bulk_delete_selected(self, request, queryset):
|
||||
count = queryset.count()
|
||||
queryset.delete()
|
||||
self.message_user(request, f'已成功删除{count}条图纸记录')
|
||||
bulk_delete_selected.short_description = '批量删除选中的图纸'
|
||||
actions = ['bulk_delete_selected']
|
||||
list_display = ('id', 'branch', 'uploaded_at', 'delete_link')
|
||||
|
||||
def delete_link(self, obj):
|
||||
url = reverse('admin:huodong_drawing_delete', args=[obj.id])
|
||||
return format_html('<a class="deletelink" href="{}">删除</a>', url)
|
||||
delete_link.short_description = '操作'
|
||||
list_filter = ('branch', 'uploaded_at')
|
||||
search_fields = ('branch__name',)
|
||||
autocomplete_fields = ['branch']
|
||||
|
||||
admin.site.register(Drawing, DrawingAdmin)
|
||||
|
||||
class PublicScreenAdmin(ModelAdmin):
|
||||
def delete_link(self, obj):
|
||||
if obj.id:
|
||||
delete_url = reverse('admin:huodong_publicscreen_delete', args=[obj.id])
|
||||
return format_html('<a href="{}" class="text-red-600 hover:text-red-900">删除</a>', delete_url)
|
||||
return '-'
|
||||
delete_link.short_description = '操作'
|
||||
|
||||
def bulk_delete_selected(self, request, queryset):
|
||||
count = queryset.count()
|
||||
queryset.delete()
|
||||
self.message_user(request, f'已成功删除{count}条公共电子屏记录')
|
||||
bulk_delete_selected.short_description = '批量删除选中的公共电子屏'
|
||||
|
||||
list_display = ('id', 'branch', 'screen_type', 'last_drill', 'delete_link')
|
||||
list_filter = ['branch', 'screen_type']
|
||||
autocomplete_fields = ['branch']
|
||||
actions = ['bulk_delete_selected']
|
||||
|
||||
admin.site.register(PublicScreen, PublicScreenAdmin)
|
||||
@admin.register(Contact)
|
||||
class ContactAdmin(ModelAdmin):
|
||||
form = ContactAdminForm # 指定自定义表单
|
||||
list_display = ('branch', 'category', 'name', 'phone', 'email') # 可选:显示分类字段
|
||||
|
||||
autocomplete_fields = ['branch']
|
||||
|
||||
@admin.register(VideoTerminal)
|
||||
class VideoTerminalAdmin(ModelAdmin):
|
||||
list_display = ('branch', 'terminal_type', 'description', 'created_at')
|
||||
list_filter = ('terminal_type', 'branch')
|
||||
search_fields = ('branch__name', 'description')
|
||||
autocomplete_fields = ['branch']
|
||||
7
fzjgact/huodong/apps.py
Normal file
7
fzjgact/huodong/apps.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class HuodongConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'huodong'
|
||||
verbose_name = '运营活动'
|
||||
0
fzjgact/huodong/management/__init__.py
Normal file
0
fzjgact/huodong/management/__init__.py
Normal file
BIN
fzjgact/huodong/management/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
fzjgact/huodong/management/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
0
fzjgact/huodong/management/commands/__init__.py
Normal file
0
fzjgact/huodong/management/commands/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
0
fzjgact/huodong/management/commands/_private.py.py
Normal file
0
fzjgact/huodong/management/commands/_private.py.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import random
|
||||
from django.core.management.base import BaseCommand
|
||||
from huodong.models import Branch
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = '随机修改所有branch实例的背景色'
|
||||
|
||||
def handle(self, *args, **kwargs):
|
||||
colors = ['#f8fafc', '#f1f5f9', '#f9fafb', '#f3f4f6', '#fafafa',
|
||||
'#f4f4f5', '#fafafa', '#f5f5f5', '#fafaf9', '#f5f5f4',
|
||||
'#fef2f2', '#fee2e2', '#fff7ed', '#ffedd5', '#fffbeb',
|
||||
'#fef3c7', '#fefce8', '#fef9c3', '#f7fee7', '#ecfccb',
|
||||
'#f0fdf4', '#dcfce7', '#ecfdf5', '#d1fae5', '#f0fdfa',
|
||||
'#ccfbf1', '#ecfeff', '#cffafe', '#f0f9ff', '#e0f2fe',
|
||||
'#eff6ff', '#dbeafe', '#eef2ff', '#e0e7ff', '#f5f3ff',
|
||||
'#ede9fe', '#faf5ff', '#f3e8ff', '#fdf4ff', '#fae8ff',
|
||||
'#fff1f2', '#ffe4e6']
|
||||
branches = Branch.objects.all()
|
||||
for branch in branches:
|
||||
branch.background_color = random.choice(colors)
|
||||
branch.save()
|
||||
self.stdout.write(self.style.SUCCESS('已成功修改所有branch实例的背景色'))
|
||||
|
||||
# 在终端运行此命令
|
||||
# python manage.py your_command_name
|
||||
50
fzjgact/huodong/migrations/0001_initial.py
Normal file
50
fzjgact/huodong/migrations/0001_initial.py
Normal file
@@ -0,0 +1,50 @@
|
||||
# Generated by Django 5.0.6 on 2024-07-09 06:35
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Branch',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('location', models.CharField(max_length=255)),
|
||||
('contact_info', models.CharField(max_length=255)),
|
||||
('description', models.TextField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Activity',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('scope', models.CharField(max_length=255)),
|
||||
('start_time', models.DateTimeField()),
|
||||
('end_time', models.DateTimeField()),
|
||||
('location', models.CharField(max_length=255)),
|
||||
('description', models.TextField()),
|
||||
('branch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='huodong.branch')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Evaluation',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('score', models.DecimalField(decimal_places=2, max_digits=4)),
|
||||
('comment', models.TextField()),
|
||||
('file_path', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('status', models.CharField(choices=[('pending', '待审核'), ('approved', '已通过'), ('rejected', '已拒绝')], default='pending', max_length=20)),
|
||||
('activity', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='huodong.activity')),
|
||||
('branch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='huodong.branch')),
|
||||
],
|
||||
),
|
||||
]
|
||||
18
fzjgact/huodong/migrations/0002_alter_activity_end_time.py
Normal file
18
fzjgact/huodong/migrations/0002_alter_activity_end_time.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2024-07-17 09:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='end_time',
|
||||
field=models.DateTimeField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
18
fzjgact/huodong/migrations/0003_alter_activity_scope.py
Normal file
18
fzjgact/huodong/migrations/0003_alter_activity_scope.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2024-07-24 02:10
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0002_alter_activity_end_time'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='scope',
|
||||
field=models.CharField(choices=[('新建', '新建'), ('搬迁', '搬迁'), ('装修', '装修'), ('其他技术问题', '其他技术问题')], max_length=255),
|
||||
),
|
||||
]
|
||||
18
fzjgact/huodong/migrations/0004_alter_activity_scope.py
Normal file
18
fzjgact/huodong/migrations/0004_alter_activity_scope.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2024-07-24 09:08
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0003_alter_activity_scope'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='scope',
|
||||
field=models.CharField(choices=[('新建', '新建'), ('搬迁', '搬迁'), ('原址装修', '原址装修'), ('其他技术问题', '其他技术问题')], max_length=255),
|
||||
),
|
||||
]
|
||||
24
fzjgact/huodong/migrations/0005_event.py
Normal file
24
fzjgact/huodong/migrations/0005_event.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 5.0.6 on 2024-07-30 08:41
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0004_alter_activity_scope'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Event',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('start_time', models.DateTimeField()),
|
||||
('end_time', models.DateTimeField(blank=True, null=True)),
|
||||
('description', models.TextField()),
|
||||
('branches', models.ManyToManyField(to='huodong.branch')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,41 @@
|
||||
# Generated by Django 5.0.6 on 2024-09-09 09:26
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0005_event'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='activity',
|
||||
options={'verbose_name': '运营活动内容', 'verbose_name_plural': '运营活动内容(新建搬迁装修和技术)'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='branch',
|
||||
options={'verbose_name': '分支机构', 'verbose_name_plural': '分支机构(基础信息)'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='event',
|
||||
options={'verbose_name': '运营事件', 'verbose_name_plural': '运营事件(其它)'},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Contact',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('category', models.CharField(choices=[('信息安全联系人', '信息安全联系人'), ('巡检人', '巡检人')], max_length=50)),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('phone', models.CharField(max_length=20)),
|
||||
('email', models.EmailField(blank=True, max_length=254)),
|
||||
('branch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='huodong.branch')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '联系人群',
|
||||
'verbose_name_plural': '联系人群',
|
||||
},
|
||||
),
|
||||
]
|
||||
18
fzjgact/huodong/migrations/0007_alter_branch_name.py
Normal file
18
fzjgact/huodong/migrations/0007_alter_branch_name.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2024-09-10 01:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0006_alter_activity_options_alter_branch_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='branch',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, unique=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.0.6 on 2024-09-10 02:29
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0007_alter_branch_name'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='contact',
|
||||
name='description',
|
||||
field=models.TextField(blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='contact',
|
||||
name='category',
|
||||
field=models.CharField(choices=[('机房/设备间巡检人', '机房/设备间巡检人'), ('信息安全联系人', '信息安全联系人')], max_length=50),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.0.6 on 2024-09-10 02:30
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0008_contact_description_alter_contact_category'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='contact',
|
||||
name='description',
|
||||
field=models.TextField(blank=True, verbose_name='描述,可不填'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='contact',
|
||||
name='email',
|
||||
field=models.EmailField(blank=True, max_length=254, verbose_name='邮箱,可不填'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='contact',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, verbose_name='姓名'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='contact',
|
||||
name='phone',
|
||||
field=models.CharField(max_length=20, verbose_name='电话'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.0.6 on 2024-09-10 02:32
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0009_alter_contact_description_alter_contact_email_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='branch',
|
||||
name='contact_info',
|
||||
field=models.CharField(max_length=255, verbose_name='主要人的联系方式'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='branch',
|
||||
name='description',
|
||||
field=models.TextField(blank=True, verbose_name='备注,可不填'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='branch',
|
||||
name='location',
|
||||
field=models.CharField(max_length=255, verbose_name='所在省份'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='branch',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, unique=True, verbose_name='分支机构名称'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.0.6 on 2024-09-10 02:39
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0010_alter_branch_contact_info_alter_branch_description_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='branch',
|
||||
name='contact_info',
|
||||
field=models.CharField(max_length=255, verbose_name='主要联系人'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='branch',
|
||||
name='description',
|
||||
field=models.TextField(blank=True, verbose_name='备注'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,79 @@
|
||||
# Generated by Django 5.0.6 on 2024-09-10 07:41
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0011_alter_branch_contact_info_alter_branch_description'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='branch',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='huodong.branch', verbose_name='分支机构'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='description',
|
||||
field=models.TextField(verbose_name='其它内容'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='end_time',
|
||||
field=models.DateTimeField(blank=True, null=True, verbose_name='结束日期'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='location',
|
||||
field=models.CharField(max_length=255, verbose_name='所在地点'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, verbose_name='活动名称'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='start_time',
|
||||
field=models.DateTimeField(verbose_name='开始日期'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='contact',
|
||||
name='branch',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='huodong.branch', verbose_name='分支机构'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='contact',
|
||||
name='category',
|
||||
field=models.CharField(choices=[('机房/设备间巡检人', '机房/设备间巡检人'), ('信息安全联系人', '信息安全联系人')], max_length=50, verbose_name='联系人分类'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='branches',
|
||||
field=models.ManyToManyField(to='huodong.branch', verbose_name='分支机构'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='description',
|
||||
field=models.TextField(verbose_name='事件描述'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='end_time',
|
||||
field=models.DateTimeField(blank=True, null=True, verbose_name='结束时间'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, verbose_name='事件名称'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='start_time',
|
||||
field=models.DateTimeField(verbose_name='开始时间'),
|
||||
),
|
||||
]
|
||||
18
fzjgact/huodong/migrations/0013_branch_background_color.py
Normal file
18
fzjgact/huodong/migrations/0013_branch_background_color.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2024-09-20 02:20
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0012_alter_activity_branch_alter_activity_description_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='branch',
|
||||
name='background_color',
|
||||
field=models.CharField(default='#EFF6FF', help_text='使用#RRGGBB格式的颜色代码', max_length=7, verbose_name='背景色'),
|
||||
),
|
||||
]
|
||||
18
fzjgact/huodong/migrations/0014_branch_category.py
Normal file
18
fzjgact/huodong/migrations/0014_branch_category.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2024-09-23 07:47
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0013_branch_background_color'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='branch',
|
||||
name='category',
|
||||
field=models.CharField(choices=[('A型', 'A型'), ('B型', 'B型'), ('C型', 'C型'), ('不适用', '不适用')], default='C型', max_length=10, verbose_name='分类'),
|
||||
),
|
||||
]
|
||||
18
fzjgact/huodong/migrations/0015_alter_activity_scope.py
Normal file
18
fzjgact/huodong/migrations/0015_alter_activity_scope.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2024-10-28 05:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0014_branch_category'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='scope',
|
||||
field=models.CharField(choices=[('新建', '新建'), ('搬迁', '搬迁'), ('原址装修', '原址装修'), ('撤销', '撤销'), ('其他技术问题', '其他技术问题')], max_length=255),
|
||||
),
|
||||
]
|
||||
18
fzjgact/huodong/migrations/0016_alter_contact_category.py
Normal file
18
fzjgact/huodong/migrations/0016_alter_contact_category.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2025-06-10 05:35
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0015_alter_activity_scope'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='contact',
|
||||
name='category',
|
||||
field=models.CharField(choices=[('机房/设备间巡检人', '机房/设备间巡检人'), ('信息安全联系人', '信息安全联系人'), ('兼岗', '兼岗'), ('安全员', '安全员')], help_text='按住 Ctrl/Command 键多选(值将以逗号分隔存储)', max_length=255, verbose_name='联系人分类'),
|
||||
),
|
||||
]
|
||||
18
fzjgact/huodong/migrations/0017_branch_equipment_image.py
Normal file
18
fzjgact/huodong/migrations/0017_branch_equipment_image.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2025-06-12 09:05
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0016_alter_contact_category'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='branch',
|
||||
name='equipment_image',
|
||||
field=models.ImageField(blank=True, null=True, upload_to='equipment_room_images/', verbose_name='设备间图片'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2025-06-12 09:25
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0017_branch_equipment_image'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='branch',
|
||||
name='equipment_image',
|
||||
field=models.ImageField(blank=True, default=None, null=True, upload_to='equipment_room_images/', verbose_name='设备间图片'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,27 @@
|
||||
# Generated by Django 5.0.6 on 2025-06-13 06:43
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0018_alter_branch_equipment_image'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='branch',
|
||||
name='equipment_image',
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EquipmentImage',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('image', models.ImageField(upload_to='equipment_room_images/')),
|
||||
('uploaded_at', models.DateTimeField(auto_now_add=True)),
|
||||
('branch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='equipment_images', to='huodong.branch')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 5.0.6 on 2025-06-13 09:40
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0019_remove_branch_equipment_image_equipmentimage'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='equipmentimage',
|
||||
options={'verbose_name': '设备间图', 'verbose_name_plural': '设备间图'},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Drawing',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('image', models.ImageField(upload_to='drawings/')),
|
||||
('uploaded_at', models.DateTimeField(auto_now_add=True)),
|
||||
('branch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='drawings', to='huodong.branch')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '图纸',
|
||||
'verbose_name_plural': '图纸',
|
||||
},
|
||||
),
|
||||
]
|
||||
27
fzjgact/huodong/migrations/0021_publicscreen.py
Normal file
27
fzjgact/huodong/migrations/0021_publicscreen.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# Generated by Django 5.0.6 on 2025-06-18 06:29
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0020_alter_equipmentimage_options_drawing'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='PublicScreen',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('image', models.ImageField(upload_to='public_screen_images/')),
|
||||
('screen_type', models.CharField(choices=[('marquee', '跑马灯'), ('advertisement', '广告屏'), ('information', '信息发布屏')], max_length=20, verbose_name='功能类型')),
|
||||
('description', models.TextField(blank=True, null=True, verbose_name='功能描述')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('branch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='public_screens', to='huodong.branch')),
|
||||
('last_drill', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='public_screens', to='huodong.event', verbose_name='最后演练事件')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,17 @@
|
||||
# Generated by Django 5.0.6 on 2025-06-18 07:53
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0021_publicscreen'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='publicscreen',
|
||||
name='created_at',
|
||||
),
|
||||
]
|
||||
19
fzjgact/huodong/migrations/0023_publicscreen_created_at.py
Normal file
19
fzjgact/huodong/migrations/0023_publicscreen_created_at.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 5.0.6 on 2025-06-18 08:43
|
||||
|
||||
import django.utils.timezone
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0022_remove_publicscreen_created_at'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='publicscreen',
|
||||
name='created_at',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now),
|
||||
),
|
||||
]
|
||||
18
fzjgact/huodong/migrations/0024_alter_event_branches.py
Normal file
18
fzjgact/huodong/migrations/0024_alter_event_branches.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2025-06-19 08:55
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0023_publicscreen_created_at'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='branches',
|
||||
field=models.ManyToManyField(related_name='events', to='huodong.branch', verbose_name='分支机构'),
|
||||
),
|
||||
]
|
||||
29
fzjgact/huodong/migrations/0025_videoterminal.py
Normal file
29
fzjgact/huodong/migrations/0025_videoterminal.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 5.0.6 on 2025-06-25 06:37
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0024_alter_event_branches'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='VideoTerminal',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('terminal_type', models.CharField(choices=[('polycom', '宝利通终端'), ('zte', '中兴终端'), ('logitech', '罗技摄像头'), ('laptop_tv', '笔记本加电视'), ('laptop_projector', '笔记本加投影仪'), ('other', '其它')], max_length=20, verbose_name='设备类型')),
|
||||
('description', models.TextField(blank=True, verbose_name='设备描述')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
|
||||
('branch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='video_terminals', to='huodong.branch', verbose_name='分支机构')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '视频设备终端',
|
||||
'verbose_name_plural': '视频设备终端',
|
||||
},
|
||||
),
|
||||
]
|
||||
18
fzjgact/huodong/migrations/0026_alter_activity_scope.py
Normal file
18
fzjgact/huodong/migrations/0026_alter_activity_scope.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2025-06-25 07:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0025_videoterminal'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='scope',
|
||||
field=models.CharField(choices=[('新建', '新建'), ('搬迁', '搬迁'), ('原址装修', '原址装修'), ('撤销', '撤销'), ('其他技术问题', '其他技术问题')], max_length=255, verbose_name='活动类型'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 5.0.6 on 2025-06-27 09:29
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0026_alter_activity_scope'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='publicscreen',
|
||||
options={'verbose_name': '公共电子屏', 'verbose_name_plural': '公共电子屏'},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='branch',
|
||||
name='is_mature',
|
||||
field=models.BooleanField(default=False, verbose_name='是否成熟'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.0.6 on 2025-07-02 07:20
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0027_alter_publicscreen_options_branch_is_mature'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='publicscreen',
|
||||
name='image',
|
||||
field=models.ImageField(blank=True, null=True, upload_to='public_screen_images/'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='publicscreen',
|
||||
name='screen_type',
|
||||
field=models.CharField(blank=True, choices=[('marquee', '跑马灯'), ('advertisement', '广告屏'), ('information', '信息发布屏')], max_length=20, null=True, verbose_name='功能类型'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.0.6 on 2025-09-01 06:13
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('huodong', '0028_alter_publicscreen_image_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='end_time',
|
||||
field=models.DateField(blank=True, null=True, verbose_name='结束日期'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='start_time',
|
||||
field=models.DateField(verbose_name='开始日期'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='end_time',
|
||||
field=models.DateField(blank=True, null=True, verbose_name='结束时间'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='start_time',
|
||||
field=models.DateField(verbose_name='开始时间'),
|
||||
),
|
||||
]
|
||||
0
fzjgact/huodong/migrations/__init__.py
Normal file
0
fzjgact/huodong/migrations/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
fzjgact/huodong/migrations/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
fzjgact/huodong/migrations/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
182
fzjgact/huodong/models.py
Normal file
182
fzjgact/huodong/models.py
Normal file
@@ -0,0 +1,182 @@
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
class Branch(models.Model):
|
||||
CATEGORY_CHOICES = (
|
||||
('A型', 'A型'),
|
||||
('B型', 'B型'),
|
||||
('C型', 'C型'),
|
||||
('不适用', '不适用'),
|
||||
)
|
||||
name = models.CharField(max_length=255, unique=True, verbose_name='分支机构名称')
|
||||
location = models.CharField(max_length=255, verbose_name='所在省份')
|
||||
contact_info = models.CharField(max_length=255, verbose_name='主要联系人')
|
||||
description = models.TextField(blank=True, verbose_name='备注')
|
||||
background_color = models.CharField(max_length=7, default='#EFF6FF', verbose_name='背景色',
|
||||
help_text='使用#RRGGBB格式的颜色代码')
|
||||
category = models.CharField(max_length=10, choices=CATEGORY_CHOICES, default='C型', verbose_name='分类')
|
||||
is_mature = models.BooleanField(default=False, verbose_name='是否成熟')
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.name} 💼' if self.is_mature else self.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = '分支机构'
|
||||
verbose_name_plural = '分支机构(基础信息)'
|
||||
|
||||
|
||||
class Contact(models.Model):
|
||||
branch = models.ForeignKey(Branch, on_delete=models.CASCADE, verbose_name='分支机构')
|
||||
CATEGORY_CHOICES = [
|
||||
('机房/设备间巡检人', '机房/设备间巡检人'),
|
||||
('信息安全联系人', '信息安全联系人'),
|
||||
('兼岗', '兼岗'),
|
||||
('安全员', '安全员')
|
||||
# 可以添加更多类别
|
||||
]
|
||||
# 修改为支持多选的 CharField
|
||||
category = models.CharField(
|
||||
max_length=255, # 增大长度(原50可能不足)
|
||||
choices=CATEGORY_CHOICES,
|
||||
verbose_name='联系人分类',
|
||||
help_text='按住 Ctrl/Command 键多选(值将以逗号分隔存储)'
|
||||
)
|
||||
name = models.CharField(max_length=255, verbose_name='姓名')
|
||||
phone = models.CharField(max_length=20, verbose_name='电话')
|
||||
email = models.EmailField(blank=True, verbose_name='邮箱,可不填')
|
||||
description = models.TextField(blank=True, verbose_name='描述,可不填')
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = '联系人群'
|
||||
verbose_name_plural = '联系人群'
|
||||
|
||||
|
||||
class Activity(models.Model):
|
||||
branch = models.ForeignKey(Branch, on_delete=models.CASCADE, verbose_name='分支机构')
|
||||
name = models.CharField(max_length=255, verbose_name='活动名称')
|
||||
scope = models.CharField(max_length=255, choices=(
|
||||
('新建', '新建'),
|
||||
('搬迁', '搬迁'),
|
||||
('原址装修', '原址装修'),
|
||||
('撤销', '撤销'),
|
||||
('其他技术问题', '其他技术问题')
|
||||
|
||||
), verbose_name='活动类型')
|
||||
start_time = models.DateField(verbose_name='开始日期')
|
||||
end_time = models.DateField(blank=True, null=True, verbose_name='结束日期') # 可以为空,表示活动尚未结束
|
||||
location = models.CharField(max_length=255, verbose_name='所在地点')
|
||||
description = models.TextField(verbose_name='其它内容')
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = '运营活动内容'
|
||||
verbose_name_plural = '运营活动内容(新建搬迁装修和技术)'
|
||||
|
||||
|
||||
class EquipmentImage(models.Model):
|
||||
branch = models.ForeignKey(Branch, related_name='equipment_images', on_delete=models.CASCADE)
|
||||
image = models.ImageField(upload_to='equipment_room_images/')
|
||||
uploaded_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"设备间图片 {self.id} - {self.branch.name}"
|
||||
|
||||
class Meta:
|
||||
verbose_name = '设备间图'
|
||||
verbose_name_plural = '设备间图'
|
||||
|
||||
|
||||
# 图纸的类
|
||||
class Drawing(models.Model):
|
||||
branch = models.ForeignKey(Branch, related_name='drawings', on_delete=models.CASCADE)
|
||||
image = models.ImageField(upload_to='drawings/')
|
||||
uploaded_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"图纸 {self.id} - {self.branch.name}"
|
||||
|
||||
class Meta:
|
||||
verbose_name = '图纸'
|
||||
verbose_name_plural = '图纸'
|
||||
|
||||
|
||||
# 公共电子屏
|
||||
class PublicScreen(models.Model):
|
||||
SCREEN_TYPES = (
|
||||
('marquee', '跑马灯'),
|
||||
('advertisement', '广告屏'),
|
||||
('information', '信息发布屏'),
|
||||
)
|
||||
branch = models.ForeignKey(Branch, on_delete=models.CASCADE, related_name='public_screens')
|
||||
image = models.ImageField(upload_to='public_screen_images/', null=True, blank=True)
|
||||
screen_type = models.CharField(max_length=20, choices=SCREEN_TYPES, verbose_name='功能类型', null=True, blank=True)
|
||||
description = models.TextField(blank=True, null=True, verbose_name='功能描述')
|
||||
last_drill = models.ForeignKey('Event', on_delete=models.SET_NULL, blank=True, null=True, related_name='public_screens', verbose_name='最后演练事件')
|
||||
created_at = models.DateTimeField(default=timezone.now)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.branch.name} - {self.get_screen_type_display()} {self.id}'
|
||||
|
||||
class Meta:
|
||||
verbose_name = '公共电子屏'
|
||||
verbose_name_plural = '公共电子屏'
|
||||
|
||||
|
||||
class Event(models.Model):
|
||||
branches = models.ManyToManyField(Branch, related_name='events', verbose_name='分支机构')
|
||||
name = models.CharField(max_length=255, verbose_name='事件名称')
|
||||
start_time = models.DateField(verbose_name='开始时间')
|
||||
end_time = models.DateField(blank=True, null=True, verbose_name='结束时间') # 可以为空,表示活动尚未结束
|
||||
description = models.TextField(verbose_name='事件描述')
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = '运营事件'
|
||||
verbose_name_plural = '运营事件(其它)'
|
||||
|
||||
|
||||
class VideoTerminal(models.Model):
|
||||
TERMINAL_TYPES = (
|
||||
('polycom', '宝利通终端'),
|
||||
('zte', '中兴终端'),
|
||||
('logitech', '罗技摄像头'),
|
||||
('laptop_tv', '笔记本加电视'),
|
||||
('laptop_projector', '笔记本加投影仪'),
|
||||
('other', '其它'),
|
||||
)
|
||||
branch = models.ForeignKey(Branch, on_delete=models.CASCADE, related_name='video_terminals', verbose_name='分支机构')
|
||||
terminal_type = models.CharField(max_length=20, choices=TERMINAL_TYPES, verbose_name='设备类型')
|
||||
description = models.TextField(blank=True, verbose_name='设备描述')
|
||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.branch.name} - {self.get_terminal_type_display()}"
|
||||
|
||||
class Meta:
|
||||
verbose_name = '视频设备终端'
|
||||
verbose_name_plural = '视频设备终端'
|
||||
|
||||
|
||||
class Evaluation(models.Model):
|
||||
activity = models.ForeignKey(Activity, on_delete=models.CASCADE)
|
||||
branch = models.ForeignKey(Branch, on_delete=models.CASCADE)
|
||||
score = models.DecimalField(max_digits=4, decimal_places=2)
|
||||
comment = models.TextField()
|
||||
file_path = models.CharField(max_length=255, blank=True, null=True)
|
||||
status = models.CharField(max_length=20,
|
||||
choices=(('pending', '待审核'), ('approved', '已通过'), ('rejected', '已拒绝')),
|
||||
default='pending')
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.activity.name} - {self.branch.name}"
|
||||
20
fzjgact/huodong/serializers.py
Normal file
20
fzjgact/huodong/serializers.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from rest_framework import serializers
|
||||
from .models import Branch, Activity, Evaluation
|
||||
|
||||
|
||||
class BranchSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Branch
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class ActivitySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Activity
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class EvaluationSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Evaluation
|
||||
fields = '__all__'
|
||||
3
fzjgact/huodong/static/huodong/input.css
Normal file
3
fzjgact/huodong/static/huodong/input.css
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
1976
fzjgact/huodong/static/huodong/output.css
Normal file
1976
fzjgact/huodong/static/huodong/output.css
Normal file
File diff suppressed because it is too large
Load Diff
12
fzjgact/huodong/templates/admin/huodong/add_form.html
Normal file
12
fzjgact/huodong/templates/admin/huodong/add_form.html
Normal file
@@ -0,0 +1,12 @@
|
||||
{% extends "admin/change_form.html" %}
|
||||
{% load i18n admin_urls static admin_modify %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
<script src="{% static 'admin/js/custom.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>自定义的添加表单</h1>
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user