POST 数据未使用中间表单在 Django 自定义管理操作中注册

问题描述 投票:0回答:1

我正在尝试为我的 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 %}

我尝试添加一个打印来查看该方法是否被调用两次,并且它只在第一次调用时打印,所以我的本能是检查代码的这一侧,但我似乎找不到解决方案。我还尝试使用具有基本表单的更简单模板,但单击“应用”按钮永远不会触发我的代码的第二部分。

python django django-admin
1个回答
0
投票

您可以制作一个中间页面来执行复杂的操作,例如表单提交、页面上显示一些额外的数据等。

创建一个操作方法 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'))
© www.soinside.com 2019 - 2024. All rights reserved.