在django-admin中将用户分配给list_display中的故障单

时间:2015-10-02 09:58:12

标签: python django django-admin

我正在开发一个Ticket系统。每张票可以分配给用户。 在django-admin中的票证list_display中,我希望有一个列显示分配给该票证的用户,或者是“为自己分配票证”链接。我知道我可以使用list_editable或自定义操作来执行此操作,但出于可用性原因,我需要list_display中的链接。

models.py

class Ticket(models.Model):
    assigned = models.ForeignKey(User, null=True)

    def assigned_to(self):
        if self.assigned:
            return self.assigned
        else:
            return "<a href="link/to/something/">Assign ticket to myself</a>"
    assigned_to.allow_tags = True

    # untested example method for assigning user to a ticket
    def assign(self, user):
        self.assigned = user
        self.save()

这是我被卡住的地方。

我需要用户点击链接,该链接将调用模型方法assign()将用户分配给故障单,然后重新加载页面,以便在list_display中显示用户名。

我希望有人可以帮助我朝着正确的方向前进。请注意,我只是一个Django初学者......

3 个答案:

答案 0 :(得分:1)

您是否考虑过使用自定义管理操作?

class TicketAdmin(admin.ModelAdmin):

    actions = [make_mine]

    def make_mine(self, request, queryset):
        """
        Set the Ticket to the current user.
        """
        for ticket in queryset:
            ticket.assigned = request.user
            ticket.save()
        self.message_user(request, _('The selected Ticket now belong to you.'))
    make_mine.short_description = _('Set the Ticket to the user')

文档:https://docs.djangoproject.com/en/1.8/ref/contrib/admin/actions/

答案 1 :(得分:1)

或者,这样的事情应该有效:

from django.contrib import admin, messages
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext_lazy as _


class TicketAdmin(admin.ModelAdmin):
    list_display = ('__str__', 'make_mine_link',)  

    def get_urls(self):
        urls = super(TicketAdmin, self).get_urls()
        opts = self.model._meta

        my_urls = patterns('',
            (r'^([0-9]+)/assign-to-me/$',
                self.admin_site.admin_view(self.make_mine), 
                name='%s_%s_make_mine' % (opts.app_label, opts.model_name)),
        )
        return my_urls + urls

    def make_mine(self, request, object_id):
        opts = self.model._meta
        redirect_to = reverse('admin:%s_%s_changelist' % (
            opts.app_label, opts.model_name), current_app=self.admin_site.name)
        ticket = get_object_or_404(self.model, pk=object_id)

        ticket.assigned = request.user
        ticket.save()

        msg = _('The selected Ticket now belong to you.')
        self.message_user(request, msg, messages.SUCCESS)
        return HttpResponseRedirect(redirect_to)

    def make_mine_link(self, obj):
        opts = self.model._meta
        url = reverse('admin:%s_%s_make_mine' % (opts.app_label, opts.model_name), args=(obj.pk,), )
        return '<a href="%s">Assign ticket to myself</a>' % url
    make_mine_link.allow_tags = True

admin.site.register(Ticket, TicketAdmin) 

我没有测试过这个。如果您有任何问题,请随时添加评论。

答案 2 :(得分:0)

您走的是正确的道路,但还有一件事要做:django会自动转义您的列值,因此您必须将其关闭。为此,只需为该方法指定allow_tags属性,如下所示:

class Ticket(models.Model):
    assigned = models.ForeignKey(User, null=True)

    def assigned_to(self):
        if self.assigned:
            return self.assigned
        else:
            return "<a href="link/to/something/">Assign ticket to myself</a>"
    assigned_to.allow_tags = True

但请记住,为字段启用allow_tags会关闭自动转义,因此您应该在其中使用format_html()以避免XSS漏洞:

class Ticket(models.Model):
    assigned = models.ForeignKey(User, null=True)

    def assigned_to(self):
        if self.assigned:
            return self.assigned
        else:
            return format_html("<a href="{link}">Assign ticket to myself</a>", link="/some/link/here")
    assigned_to.allow_tags = True