Skip to content

Instantly share code, notes, and snippets.

@Ingco
Created February 4, 2020 12:02
Show Gist options
  • Save Ingco/fc0ab7dfc55954aed21ed7c6a4517fba to your computer and use it in GitHub Desktop.
Save Ingco/fc0ab7dfc55954aed21ed7c6a4517fba to your computer and use it in GitHub Desktop.
question
def make_readonly_field_for_instance(
parent_obj, obj, template_path: str = "", extra_context: dict = None
) -> callable:
"""
Dynamically creating new read-only fields for ModelAdmin classes
:param parent_obj: Models instance from admin class
:param obj: The object for which we are creating the field
:param template_path: Template for rendering
:param extra_context: dynamic context
:return: callable
"""
def new_readonly_field(parent_obj, *args, **kwargs):
"""
Generate ModelAdmin field for display custom HTML
:param parent_obj: Instance from ModelAdmin
:return: callable
"""
engine_template = Engine(
app_dirs=True,
libraries={
"static": "django.templatetags.static",
"i18n": "django.templatetags.i18n",
},
).get_template(template_path)
context = Context(
{
"current_object": obj,
"parent_obj": parent_obj,
**extra_context,
}
)
return engine_template.render(context)
return new_readonly_field
class MyAdmin(admin.ModelAdmin):
...
def get_fields(self, request, obj=None):
fields = super(InvoiceAdmin, self).get_fields(request, obj)
if obj is None:
return fields
fields = list(fields) if not isinstance(fields, list) else fields
# Add dynamic readonly fields for display PDF and Email buttons
templates_list = obj.status.templates.filter(
api_id__isnull=False, is_active=True
).all()
email_templates = EmailTemplateService().get_email_templates()
print(email_templates)
if len(templates_list) == 0:
return fields
"""
Generate HTML with links to generate PDF-file and links to send emails.
Add new methods for the admin class by the number of templates
"""
template_path = "invoice/admin/invoice_pdf_buttons_form_row.html"
for template in templates_list:
name_method = f"get_template_{template.pk}"
# Create new field
new_readonly_field = make_readonly_field_for_instance(
obj,
template,
template_path,
extra_context={
"email_templates": email_templates,
"datetime_now": timezone.now(),
"send_logs": template.invoiceemallog_pdftemplate.all()
},
)
new_readonly_field.__name__ = name_method
new_readonly_field.short_description = _(template.__str__())
# Add new field to ModelAdmin
self.dynamic_fields.append(name_method)
if name_method not in fields:
fields.insert(fields.index("get_invoice_lines_block"), name_method)
if not hasattr(self, name_method):
setattr(self, name_method, new_readonly_field)
return fields
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment