如何通过HTTP GET参数预填充Wagtail Admin UI字段(基于ModelViewSet)
基于Wagtail ModelViewSet实现GET参数预填充表单字段
核心实现方案(后端视图层处理)
直接重写ModelViewSet的创建视图,通过get_initial方法读取GET参数并设置表单初始值,完全适配Wagtail新版的ModelViewSet,无需依赖废弃的ModelAdmin:
1. 自定义创建视图类
继承Wagtail的ModelCreateView,重写get_initial方法从request的GET参数中提取并转换日期值:
from django.utils.dateparse import parse_datetime from wagtail.admin.viewsets.model import ModelCreateView from .models import EventOccurrence class CustomEventOccurrenceCreateView(ModelCreateView): def get_initial(self): # 获取父类的初始值 initial = super().get_initial() # 读取并转换GET参数中的日期 start_str = self.request.GET.get('start') end_str = self.request.GET.get('end') if start_str: start_dt = parse_datetime(start_str) if start_dt: initial['start'] = start_dt if end_str: end_dt = parse_datetime(end_str) if end_dt: initial['end'] = end_dt return initial
2. 绑定到自定义ModelViewSet
创建自己的ModelViewSet,指定使用上面的自定义创建视图:
from wagtail.admin.viewsets.model import ModelViewSet from .models import EventOccurrence class EventOccurrenceModelViewSet(ModelViewSet): model = EventOccurrence create_view_class = CustomEventOccurrenceCreateView # 按需配置其他属性:fields, form_class, menu_label等 fields = ['event', 'start', 'end', 'location'] menu_label = '事件场次' menu_icon = 'calendar'
3. 注册ViewSet到Wagtail Admin
在wagtail_hooks.py中注册这个ViewSet:
from wagtail import hooks from .viewsets import EventOccurrenceModelViewSet @hooks.register('register_admin_viewset') def register_event_occurrence_viewset(): return EventOccurrenceModelViewSet('event_occurrence', url_prefix='event-occurrence')
现在访问类似/admin/event-occurrence/new?start=2024-05-01T09:00:00&end=2024-05-01T10:00:00的地址时,表单的start和end字段会自动被预填充。
可选方案:模态框内嵌预填充表单
如果想在日历页面直接弹出模态框创建场次(无需跳转到独立表单页),可以用Wagtail的ModalWorkflow实现,同样后端处理GET参数:
1. 自定义模态框视图
from django.shortcuts import render from django.utils.dateparse import parse_datetime from wagtail.admin.modal_workflow import render_modal_workflow from .forms import EventOccurrenceForm def event_occurrence_modal(request): initial = {} start_str = request.GET.get('start') end_str = request.GET.get('end') if start_str: initial['start'] = parse_datetime(start_str) if end_str: initial['end'] = parse_datetime(end_str) if request.method == 'POST': form = EventOccurrenceForm(request.POST, initial=initial) if form.is_valid(): occurrence = form.save() # 返回模态框关闭信号及创建结果 return render_modal_workflow( request, None, None, {'action': 'choose', 'result': {'id': occurrence.id, 'string': str(occurrence)}} ) else: form = EventOccurrenceForm(initial=initial) return render_modal_workflow( request, 'admin/event_occurrence_modal.html', None, {'form': form} )
2. 创建模态框模板(admin/event_occurrence_modal.html)
{% extends "wagtailadmin/modal_workflow/base.html" %} {% load wagtailadmin_tags %} {% block form %} <form action="{% url 'event_occurrence_modal' %}" method="POST"> {% csrf_token %} {% for field in form %} {% include "wagtailadmin/shared/field.html" with field=field %} {% endfor %} <div class="submit"> <button type="submit" class="button button-primary">保存场次</button> </div> </form> {% endblock %}
3. 注册模态框路由
在项目的urls.py中添加路由:
from django.urls import path from .views import event_occurrence_modal urlpatterns = [ # 其他路由... path('admin/event-occurrence/modal/', event_occurrence_modal, name='event_occurrence_modal'), ]
4. FullCalendar中调用模态框
在日历页面的JS中,通过Wagtail的modalWorkflow打开预填充的模态框:
document.addEventListener('DOMContentLoaded', function() { const calendar = new FullCalendar.Calendar(document.getElementById('calendar'), { selectable: true, select: function(info) { const start = encodeURIComponent(info.start.toISOString()); const end = encodeURIComponent(info.end.toISOString()); window.modalWorkflow({ url: `/admin/event-occurrence/modal?start=${start}&end=${end}`, response: function(data) { if (data.action === 'choose') { // 刷新日历显示新创建的场次 calendar.refetchEvents(); } } }); } }); calendar.render(); });
关于ChooserWidget的说明
ChooserWidget主要用于选择已有对象,而非创建新对象并预填充字段,因此不太适配你的场景。如果需要关联已有Event到新的EventOccurrence,可以在表单中保留默认的Event选择器,结合上面的预填充逻辑一起使用即可。
内容的提问来源于stack exchange,提问作者Vorletzter
相关产品推荐
相关产品推荐

