我正在尝试为我的 Django 模型添加自定义管理操作。目标是向用户显示一个表单,他们可以在其中选择一个组,该组将链接到我选择的所有候选人。
我的问题是代码在渲染部分工作,并且显示了表单。但是,当我单击“应用”时,我的代码永远不会进入
if 'apply' in request.POST
条件。似乎该代码永远不会被第二次调用。
这是我的代码的相关部分:
CandidateAdmin.py
from django.contrib import admin
from django.utils.safestring import mark_safe
from exem_poi.models import Candidate
from django.urls import reverse
from django.utils.html import format_html
from django.http import HttpResponseRedirect
from django.shortcuts import render
from exem_poi.views.utils import convert_to_wgs84
from exem_poi.models.Candidate import Group
@admin.register(Candidate)
class CandidateAdmin(admin.ModelAdmin):
list_display = ('batiment_construction_id', 'emitters_100m', 'height', 'display_owners', 'is_public')
list_filter = ('emitters_100m', 'height', 'is_public')
search_fields = ('batiment_construction_id', 'emitters_100m', 'height', 'is_public')
readonly_fields = ('centroid',)
actions = ['assign_to_group']
def assign_to_group(self, request, queryset):
# Handle the form submission for assigning candidates to a group
print(request.POST)
if 'apply' in request.POST:
group_id = request.POST.get('group_id')
group = Group.objects.get(id=group_id)
for candidate in queryset:
group.candidates.add(candidate)
self.message_user(request, f'Successfully assigned candidates to group {group.name}')
return HttpResponseRedirect(request.path)
groups = Group.objects.all()
context = {'groups': groups, 'candidates': queryset}
return render(request, 'admin/assign_to_group.html', context)
分配给组.html
<!-- admin/assign_to_group.html -->
{% extends 'admin/base_site.html' %}
{% block content %}
<form method="post" action="">
{% csrf_token %}
<label for="group_id">Select a group:</label>
<select name="group_id" required>
{% for group in groups %}
<option value="{{ group.id }}">{{ group.name }}</option>
{% endfor %}
</select>
<input type="hidden" name="action" value="assign_to_group">
<input type="submit" name="apply" value="Apply">
</form>
{% endblock %}
我尝试添加一个打印来查看该方法是否被调用两次,并且它只在第一次调用时打印,所以我的本能是检查代码的这一侧,但我似乎找不到解决方案。我还尝试使用具有基本表单的更简单模板,但单击“应用”按钮永远不会触发我的代码的第二部分。
您可以制作一个中间页面来执行复杂的操作,例如表单提交、页面上显示一些额外的数据等。
创建一个操作方法 assign_to_group(),该方法重定向到中间页面 url 并将 selected object_ids 作为带有 url 的参数传递。已向管理员注册此网址。
创建一个视图,在其中使用表单渲染数据,并在表单提交后处理操作。
管理员.py
def assign_to_group(modeladmin, request, queryset):
selected = queryset.values_list("pk", flat=True)
selected_ids = ",".join(str(pk) for pk in selected)
intermediate_page_url = "%s?ids=%s" % (reverse("admin:group_assign"), selected_ids)
return HttpResponseRedirect(intermediate_page_url)
@admin.register(Candidate)
class CandidateAdmin(admin.ModelAdmin):
...
actions = [assign_to_group]
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("group-assign/", self.admin_site.admin_view(GroupAssignView.as_view()), name="group_assign"),
]
return custom_urls + urls
视图.py
from django.views import View
class GroupAssignView(View):
def get(self, request):
# you can get selected object ids for action
ids = request.GET.get('ids')
# Now you can do everything like render form with data
context = dict()
...
return render(request, 'admin/assign_to_group.html', context)
def post(self, request):
data = request.POST
# After form submission you get form-data , complete your action
...
# finally redirected back to the original change list page.
return redirect(reverse('admin:<app_name>_candidate_changelist'))