I'm trying to learn on model admin template customization.
I need that custom template can read some data stored/passed in 'extra_context'
admin.py
from django.contrib import admin
from .models import MailTemplate
# Register your models here.
class MailTemplateAdmin(admin.ModelAdmin):
change_form_template = 'change_form_htmx.html'
def changeform_view(self,request, object_id=None, form_url="", extra_context=None):
extra_context = extra_context or {}
extra_context['myvar']='this is myvar'
return super(MailTemplateAdmin, self).changeform_view(request, object_id=object_id, form_url=form_url, extra_context=extra_context)
admin.site.register(MailTemplate,MailTemplateAdmin)
template 'change_form_htmx.html'
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
{% block extrahead %}{{ block.super }}
<script src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" href="{% static "admin/css/forms.css" %}">{% endblock %}
{% block coltype %}colM{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
{% translate 'Home' %}
› {{ opts.app_config.verbose_name }}
› {% if has_view_permission %}{{ opts.verbose_name_plural|capfirst }}{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
› {% if add %}{% blocktranslate with name=opts.verbose_name %}Add {{ name }}{% endblocktranslate %}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% endif %}
{% block content %}<div id="content-main">
<!--- add htmx -->
<script src="https://unpkg.com/htmx.org#1.6.0"></script>
{% block object-tools %}
{% if change and not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
{% change_form_object_tools %}
{% endblock %}
</ul>
{% endif %}
{% endblock %}
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}{% if form_url %}action="{{ form_url }}" {% endif %}method="post" id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
<div>
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1">{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}">{% endif %}
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
{% if errors %}
<p class="errornote">
{% blocktranslate count counter=errors|length %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktranslate %}
</p>
{{ adminform.form.non_field_errors }}
{% endif %}
{% block field_sets %}
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% endblock %}
{% block after_field_sets %}{% endblock %}
{% block inline_field_sets %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% endblock %}
<div id="some_buttons">
<!-- here we have button for add and delete row-->
from extra_context = {{ extra_context.myvar }}
</div>
{% block after_related_objects %}{% endblock %}
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
{% block admin_change_form_document_ready %}
<script id="django-admin-form-add-constants"
src="{% static 'admin/js/change_form.js' %}"
{% if adminform and add %}
data-model-name="{{ opts.model_name }}"
{% endif %}
async>
</script>
{% endblock %}
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% endblock %}
There is no error occured, but the extra_content['myval'] is not showed.
Kindly please tell how is the proper way to send extra_context from ModelAdmin and read it in template.
Sincerely
-bino-
Argghh my vault.
It work now.
I replace (in template)
{{ extra_context.myvar }}
with
{{myvar}}
Related
I'm using django-tables2 to render my data in tables in the template..
everything is rendered fine with pagination..
The Designer of our company wants to change the Display of data into blocks instead of simple table. the following picture may explain more.
I Want to ask if I can use Django tables2 in this case ..since I don't want to loose the pagination
Is it possible to custom the django_tables2/table.html file to only fit this case (because I'm using django-tables2 in many other pages in the project)?
Any other ideas may be helpful.
Thanks in advance :)
Yes, you can create a custom template (based on django_tables2/table.html) and set a specific table's template Meta attribute to its path:
import django_tables2 as tables
class Table(tables.Table):
# columns
class Meta:
template = 'table-blocks.html'
or use the template argument to the Table constructor:
table = Table(queryset, template='table-blocks.html')
or use the second argument of the {% render_table %} templatetag:
{% load django_tables2 %}
{% render_table queryset 'table-blocks.html' %}
I was having the same requirement and i had been able to do it. To achieve the desired results i have used bootstrap4 and modified the "django_tables2/bootstrap4.html" template. My modified template only displays blocks which can further be enhanced by embedding more css in it.
{% load django_tables2 %}
{% load i18n %}
{% block table-wrapper %}
<div class="container-fluid relative animatedParent animateOnce p-0" >
{% block table %}
{% block table.tbody %}
<div class="row no-gutters">
<div class="col-md-12">
<div class="pl-3 pr-3 my-3">
<div class="row">
{% for row in table.paginated_rows %}
{% block table.tbody.row %}
<div class="col-md-6 col-lg-3 my-3">
<div class="card r-0 no-b shadow2">
{% for column, cell in row.items %}
<div class="d-flex align-items-center justify-content-between">
<div class="card-body text-center p-5">
{% if column.localize == None %}{{ cell }}{% else %}{% if column.localize %}{{ cell|localize }}{% else %}{{ cell|unlocalize }}{% endif %}{% endif %}
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock table.tbody.row %}
{% empty %}
{% if table.empty_text %}
{% block table.tbody.empty_text %}
<tr><td colspan="{{ table.columns|length }}">{{ table.empty_text }}</td></tr>
{% endblock table.tbody.empty_text %}
{% endif %}
{% endfor %}
</div></div></div> </div>
{% endblock table.tbody %}
{% block table.tfoot %}
{% if table.has_footer %}
<tfoot {{ table.attrs.tfoot.as_html }}>
<tr>
{% for column in table.columns %}
<td {{ column.attrs.tf.as_html }}>{{ column.footer }}</td>
{% endfor %}
</tr>
</tfoot>
{% endif %}
{% endblock table.tfoot %}
{% endblock table %}
</div>
{% block pagination %}
{% if table.page and table.paginator.num_pages > 1 %}
<nav aria-label="Table navigation">
<ul class="pagination justify-content-center">
{% if table.page.has_previous %}
{% block pagination.previous %}
<li class="previous page-item">
<a href="{% querystring table.prefixed_page_field=table.page.previous_page_number %}" class="page-link">
<span aria-hidden="true">«</span>
{% trans 'previous' %}
</a>
</li>
{% endblock pagination.previous %}
{% endif %}
{% if table.page.has_previous or table.page.has_next %}
{% block pagination.range %}
{% for p in table.page|table_page_range:table.paginator %}
<li class="page-item{% if table.page.number == p %} active{% endif %}">
<a class="page-link" {% if p != '...' %}href="{% querystring table.prefixed_page_field=p %}"{% endif %}>
{{ p }}
</a>
</li>
{% endfor %}
{% endblock pagination.range %}
{% endif %}
{% if table.page.has_next %}
{% block pagination.next %}
<li class="next page-item">
<a href="{% querystring table.prefixed_page_field=table.page.next_page_number %}" class="page-link">
{% trans 'next' %}
<span aria-hidden="true">»</span>
</a>
</li>
{% endblock pagination.next %}
{% endif %}
</ul>
</nav>
{% endif %}
{% endblock pagination %}
{% endblock table-wrapper %}
I have the following:
layout.html
{% if enableEntry or enableExit %}
{% from "cp.layout.html" import entry, exit %}
{% endif %}
<!DOCTYPE html>
<html lang="en">
<body>
{% if enableEntry %}{{ entry }}{% endif %}
{% if enableExit %}{{ exit }}{% endif %}
{% block body %}{% endblock %}
</body>
</html>
cp.layout.html
{% set entry %}
...
{% if offer.text_id == "mcd" %}
Mcdonald
{% elif offer.text_id == "bk" %}
Burger King
{% endif %}
...
{% endset %}
in my view:
def test():
.... (offer is defined here) ...
return render_template('layout.html', offer=offer)
I am getting an error that UndefinedError: 'offer' is undefined
Is there a way to pass variables that have global scope in the view to {% set %} blocs?
Seems like you never include your test.html under layout.html
I not sure is this help, this is my jinja 2 template design u can try
layout.html
{%- extends "test.html" %}
{# {% include "test.html" %} #}
{% block content %}
{{ super() }}
{%- endblock %}
test.html
{% block content %}
<div>
<h1>{{ offer }}</h1>
</div>
{% endblock %}
Let me know is this method work will give more explanation later
On DetailView template I am not able to print name,date of post only '|' sign is being printed but on ListView it is working fine. Here is code written in files. Thanks!!
blog/urls.py
urlpatterns = patterns('',url(r'^$', ListView.as_view(queryset =
Blog.objects.all(), template_name ='blog.html')),
url(r'^(?P<pk>\d+)/$', DetailView.as_view(model=Blog, template_name='detail.html')), )
blog.html
{% extends 'base.html' %}
{% block content %}
{% for post in object_list %}
<ul> {{ post.name }} ||{{ post.date }}</ul>
{% endfor %}
{% endblock %}
detial.html
{% extends 'base.html' %}
{% block content %} <h2> <a href="/blog/{{ post.id }}">{{ post.name }}
</a>||{{ post.date }}</h2> {% endblock %}
context_object_name Designates the name of the variable to use in the context. Default is "object"
Try
{% extends 'base.html' %}
{% block content %} <h2> <a href="/blog/{{ object.id }}">{{ object.name }}
</a>||{{ object.date }}</h2> {% endblock %}
See SingleObjectMixin and making-friendly-template-contexts
The django contrib comments form i'm using:
{% get_comment_form for post as form %}
<form action="{% comment_form_target %}" method="post">{% csrf_token %}
{% if next %}
<div><input type="hidden" name="next" value="{{ next }}" /></div>
{% endif %}
{% for field in form %}
{% if field.is_hidden %}
<div>{{ field }}</div>
{% else %}
{% if field.name == 'comment' %}
{% if field.errors %}{{ field.errors }}{% endif %}
<p
{% if field.errors %} class="error"{% endif %}
{% ifequal field.name "honeypot" %} style="display:none;"{% endifequal %}>
{{ field.label_tag }} {{ field }}
</p>
{% endif %}
{% endif %}
{% endfor %}
<p class="submit">
<input type="submit" name="post" class="submit-post" value="{% trans "Post" %}" />
</p>
</form>
After submitting the form, it redirects to http://127.0.0.1:8000/comments/posted/?c=..
That means it calls the template django/contrib/comments/templates/comments/posted.html
The content of django/contrib/comments/templates/comments/posted.html:
{% extends "comments/base.html" %}
{% load i18n %}
{% block title %}{% trans "Thanks for commenting" %}.{% endblock %}
{% block content %}
<h1>{% trans "Thank you for your comment" %}.</h1>
{% endblock %}
That doesn't extends my project's base.html.
I need to customize/override that template so that it extends my project's base.html. How can i do that?
If i can't do that, then if i upload my django web project on server, then how would i edit the content of django/contrib/comments/templates/comments/posted.html so that it looks like that:
{% extends "path/to/myproject/templates/base.html" %}
{% load i18n %}
{% block title %}{% trans "Thanks for commenting" %}.{% endblock %}
{% block content %}
<h1>{% trans "Thank you for your comment" %}.</h1>
{% endblock %}
On local pc, for this time i changed/edited the content of django/contrib/comments/templates/comments/posted.html hard-coded to extends my project base.html.
Can anyone give some idea to solve this? I have searched a lot to solve this.
Just override it in your project's "templates" directory:
<project_root>/templates/comments/posted.html
It doesn't seem to be well documented in either the comments app or Django's general template documentation, but it works the same as overriding admin templates (which is documented).
I can edit a parent child relationship using the TablularInline and StackedInline classes, however I would prefer to list the child relationships as a change list as there is a lot of information and the forms are too big. Is there an inline change list available in DJango admin or a way or creating one?
There's no such functionality built in, but I don't think it would be hard to create your own AdminInline subclass (and an accompanying template for it) that would do this. Just model it off TabularInline, but display fields' data directly instead of rendering form fields.
So I was actually able to achieve this with quite the hack. Django Admin needs some updates and InlineAnything would be one.
Download Library: https://github.com/smartlgt/django-fakeinline
class MyInlineTest(FakeInline):
def __init__(self, parent_model, admin_site):
super().__init__(parent_model, admin_site)
self.template = Template('')
self.admin_site = admin_site
def get_fields(self, request, obj=None):
dpaa = DisplayProductAccessAdmin(DisplayProductAccess, self.admin_site)
dpaa.change_list_template = 'test.html'
self.template = Template(dpaa.changelist_view(request, {}).rendered_content)
return FakeInline.get_fields(self, request, obj=obj)
Then in your test.html, take most of the contents of the change_list.html from Django. Since we're using Jazzmin let's go with that.
{% load i18n admin_urls static admin_list jazzmin %}
{% block extrastyle %}
<link rel="stylesheet" href="{% static 'vendor/select2/css/select2.min.css' %}">
{% if cl.formset or action_form %}
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
{% endif %}
{{ media.css }}
{% if not actions_on_top and not actions_on_bottom %}
<style>
#changelist table thead th:first-child {width: inherit}
</style>
{% endif %}
{% endblock %}
{% block extrahead %}
{{ media.js }}
{% endblock %}
{% block content %}
<div class="col-12">
<div class="card card-primary card-outline">
<div class="card-header">
<h4 class="card-title">{{ title }}{% block pretitle %}{% endblock %}</h4>
<div class="card-tools form-inline">
{% block date_hierarchy %}{% if cl.date_hierarchy %}{% date_hierarchy cl %}{% endif %}{% endblock %}
{% block search %}
{% search_form cl %}
{% endblock %}
</div>
</div>
<div class="card-body">
<form id="changelist-form" method="post"{% if cl.formset and cl.formset.is_multipart %}enctype="multipart/form-data"{% endif %} novalidate>{% csrf_token %}
<div id="content-main">
{% if cl.formset and cl.formset.errors %}
<p class="errornote">
{% if cl.formset.total_error_count == 1 %}
{% trans "Please correct the error below." %}
{% else %}
{% trans "Please correct the errors below." %}
{% endif %}
</p>
{{ cl.formset.non_form_errors }}
{% endif %}
<div class="module{% if cl.has_filters %} filtered{% endif %}" id="changelist">
<div class="row">
<div class="col-12">
{% if cl.formset %}
<div>{{ cl.formset.management_form }}</div>
{% endif %}
{% block result_list %}
<div class="row">
<div class="col-12 col-sm-8">
{% if action_form and actions_on_top and cl.show_admin_actions %}
{% admin_actions %}
{% endif %}
</div>
<div class="col-12 col-sm-4">
{% block object-tools %}
{% block object-tools-items %}
{% change_list_object_tools %}
{% endblock %}
{% endblock %}
</div>
</div>
<hr/>
{% result_list cl %}
{% if action_form and actions_on_bottom and cl.show_admin_actions %}
<div class="row">
<div class="col-12">
{% admin_actions %}
</div>
</div>
{% endif %}
{% endblock %}
</div>
</div>
<div class="row">
{% block pagination %}{% pagination cl %}{% endblock %}
</div>
</div>
</div>
</form>
</div>
</div>
<br class="clear"/>
</div>
{% endblock %}
{% block extrajs %}
<script type="text/javascript" src="{% static 'vendor/select2/js/select2.min.js' %}"></script>
<script type="text/javascript" src="{% static 'jazzmin/js/change_list.js' %}"></script>
{% endblock %}