show custom fields in contact admin
[prawokultury.git] / contact / admin.py
1 from django.contrib import admin
2 from django.forms import ModelForm
3 from .models import Contact
4 from django.utils.translation import ugettext as _
5 from .forms import contact_forms, admin_list_width
6 from django.template import Template
7 from django.utils.safestring import mark_safe
8
9
10 class ContactAdminMeta(admin.ModelAdmin.__metaclass__):
11     def __getattr__(cls, name):
12         if name.startswith('admin_list_'):
13             return lambda self: ""
14         raise AttributeError, name
15
16
17 class ContactAdmin(admin.ModelAdmin):
18     __metaclass__ = ContactAdminMeta
19     date_hierarchy = 'created_at'
20     list_display = ['created_at', 'contact', 'form_tag'] + \
21         ["admin_list_%d" % i for i in range(admin_list_width)]
22     fields = ['form_tag', 'created_at', 'contact', 'ip']
23     readonly_fields = ['form_tag', 'created_at', 'contact', 'ip']
24
25     def admin_list(self, obj, nr):
26         try:
27             field_name = contact_forms[obj.form_tag].admin_list[nr]
28         except BaseException, e:
29             return ''
30         else:
31             return obj.body.get(field_name, 'y')
32
33     def __getattr__(self, name):
34         if name.startswith('admin_list_'):
35             nr = int(name[len('admin_list_'):])
36             return lambda obj: self.admin_list(obj, nr)
37         raise AttributeError, name
38
39     def change_view(self, request, object_id, extra_context=None):
40         if object_id:
41             try:
42                 instance = Contact.objects.get(pk=object_id)
43                 assert isinstance(instance.body, dict)
44             except (Contact.DoesNotExist, AssertionError):
45                 pass
46             else:
47                 # Create readonly fields from the body JSON.
48                 body_fields = ['body__%s' % k for k in instance.body.keys()]
49                 attachments = list(instance.attachment_set.all())
50                 body_fields += ['body__%s' % a.tag for a in attachments]
51                 self.readonly_fields.extend(body_fields)
52
53                 # Find the original form.
54                 try:
55                     orig_fields = contact_forms[instance.form_tag]().fields
56                 except KeyError:
57                     orig_fields = {}
58
59                 # Try to preserve the original order.
60                 admin_fields = []
61                 orig_keys = list(orig_fields.keys())
62                 while orig_keys:
63                     key = orig_keys.pop(0)
64                     key = "body__%s" % key
65                     if key in body_fields:
66                         admin_fields.append(key)
67                         body_fields.remove(key)
68                 admin_fields.extend(body_fields)
69
70                 self.fieldsets = [
71                     (None, {'fields': self.fields}),
72                     (_('Body'), {'fields': admin_fields}),
73                 ]
74
75                 # Create field getters for fields and attachments.
76                 for k, v in instance.body.items():
77                     f = (lambda v: lambda self: v)(v)
78                     f.short_description = orig_fields[k].label if k in orig_fields else _(k)
79                     setattr(self, "body__%s" % k, f)
80
81                 download_link = "<a href='%(url)s'>%(url)s</a>"
82                 for attachment in attachments:
83                     k = attachment.tag
84                     link = mark_safe(download_link % {
85                             'url': attachment.get_absolute_url()})
86                     f = (lambda v: lambda self: v)(link)
87                     f.short_description = orig_fields[k].label if k in orig_fields else _(k)
88                     setattr(self, "body__%s" % k, f)
89         return super(ContactAdmin, self).change_view(request, object_id,
90             extra_context=extra_context)
91
92
93 admin.site.register(Contact, ContactAdmin)