Add support for linked objects in backend forms
authorMagnus Hagander <magnus@hagander.net>
Sat, 16 Jun 2018 20:16:00 +0000 (22:16 +0200)
committerMagnus Hagander <magnus@hagander.net>
Wed, 20 Jun 2018 11:47:59 +0000 (13:47 +0200)
This is things that are "sub-objects" of another object. In the admin
interface we typically used inline forms for it, but it will be easier
to use as simple linked objects.

Recursively call into the existing backend form handler to manage them,
as all the code is already in place.

postgresqleu/confreg/backendforms.py
postgresqleu/confreg/backendviews.py
template/confreg/admin_backend_form_content.html

index 8583d04d48ed67f16f11cb5c5f9ed2380f47c640..aca0aaa1df53621c57b9b2d27053af0ed4378ed9 100644 (file)
@@ -50,6 +50,7 @@ class BackendForm(ConcurrentProtectedModelForm):
        coltypes = {}
        readonly_fields = []
        file_fields = []
+       linked_objects = {}
 
        def __init__(self, conference, *args, **kwargs):
                self.conference = conference
index 0693b9c84eed5a68af88785fd93a62af2f7c61ce..e18bd6fd7a921eb8e652ef3ea65ac68b4245b2bc 100644 (file)
@@ -160,6 +160,7 @@ def backend_process_form(request, urlname, formclass, id, cancel_url='../', save
                'breadcrumbs': breadcrumbs,
                'allow_delete': allow_delete and instance.pk,
                'adminurl': adminurl,
+               'linked': [(url, handler, handler.get_list(form.instance)) for url, handler in form.linked_objects.items() if form.instance],
        })
 
 def backend_handle_copy_previous(request, formclass, restpieces, conference):
@@ -295,11 +296,47 @@ def backend_list_editor(request, urlname, formclass, resturl, allow_new=True, al
 
        # Is it an id?
        try:
-               id = int(resturl)
+               id = int(restpieces[0])
        except ValueError:
                # No id. So we don't know. Fail.
                raise Http404()
 
+       if len(restpieces) > 2 and restpieces[1] in formclass.linked_objects:
+               # We are editing a sub-object!
+
+               handler = formclass.linked_objects[restpieces[1]]
+               masterobj = formclass.Meta.model.objects.get(pk=id, conference=conference)
+
+               if restpieces[2] == 'new':
+                       subid = None
+               else:
+                       try:
+                               subid = int(restpieces[2])
+                               subobj = handler.get_object(masterobj, subid)
+                               if not subobj:
+                                       raise Http404()
+                       except ValueError:
+                               # No proper subid. So fail.
+                               raise Http404()
+
+               return backend_process_form(request,
+                                                                       urlname,
+                                                                       handler.get_form(),
+                                                                       subid,
+                                                                       breadcrumbs=breadcrumbs + [
+                                                                               ('../../../', formclass.Meta.model._meta.verbose_name_plural.capitalize()),
+                                                                               ('../../', masterobj),
+                                                                       ],
+                                                                       cancel_url='../../',
+                                                                       saved_url='../../',
+                                                                       conference=conference,
+                                                                       bypass_conference_filter=True,
+                                                                       instancemaker=handler.get_instancemaker(masterobj),
+               )
+
+       if len(restpieces) > 1:
+               raise Http404()
+
        return backend_process_form(request,
                                                                urlname,
                                                                formclass,
index 51d6447cb72d0129a4e0a4a2460156272c09e487..04cafcf292c1260b0ab4c2c8b1c62bcf92314224 100644 (file)
 {{field}}
  {%endif%}
 {%endfor%}
+
+{%for url, handler, entries in linked %}
+<div class="form-group">
+  <label class="control-label col-lg-3">{{handler.title}}:</label>
+  <div class="col-lg-9 controls">
+    <table class="table table-bordered table-striped table-hover table-condensed">
+{%for id,title,description in entries%}
+    <tr>
+      <td><a href="{{url}}/{{id}}/">{{title}}</a></td>
+      <td>{{description}}</td>
+    </tr>
+{%endfor%}
+    </table>
+{%if form.instance.id%}
+    <a href="{{url}}/new/" class="btn btn-default">Add {{handler.singular}}</a>
+{%endif%}
+  </div>
+</div>
+{%endfor%}
+
 {%if not nobuttons%}
  <div class="form-group">
   <div class="col-lg-12">