I am using 2 django packages: Admin sortable (For changing the order of models) and Django import export (For importing csv directly into my models).
The problem is that if I add the 2 packages into my model admin e.g.
class CategoryAdmin(SortableAdmin, ImportExportModelAdmin):
they override each other.
The buttons either show only for the Admin sortable or the Django import export. Is there anyway I can integrate both of them together? Alternatively, is there another package I can swap out so that I can achieve the same functions (1. change the order of models and 2. import csv directly into models)
I was able to solve this by overriding the template used on the page. Both Admin Sortable and Django Import Export override the admin change_list.html template in different ways, which is why they don't play nice together.
I used the adminsortable template as my base (Found in site_packages/adminsortable/templates/adminsortable/change_list_with_sort_link.html), and added some pieces from the django import export template (Found in site_packages/import_export/templates/admin/import_export/change_list_import_export.html) to get this merged template:
{% extends change_list_template_extends %}
{% load i18n %}
{% block object-tools-items %}
{% for sorting_filter in sorting_filters %}
<li>
{% trans 'Change Order of' %} {{ sorting_filter }}
</li>
{% empty %}
<li>
{% trans 'Change Order' %}
</li>
{% endfor %}
{% include "admin/import_export/change_list_import_item.html" %}
{% include "admin/import_export/change_list_export_item.html" %}
{{ block.super }}
{% endblock %}
The lines:
{% include "admin/import_export/change_list_import_item.html" %}
{% include "admin/import_export/change_list_export_item.html" %}
Add the import export buttons to the template.
Then, you need to tell django to use this template. The SortableAdminBase class has a field called sortable_change_list_with_sort_link_template which you can override to use your new custom template. So your admin class will look like:
class CategoryAdmin(ImportExportMixin, SortableAdmin):
sortable_change_list_with_sort_link_template = 'admin/category/change_list_import_export_sortable.html'
Assuming you put your custom template in admin/category/change_list_import_export_sortable.html
If all works well, you should be getting all 3 buttons appearing at the top of your admin page:
Django Import Export Admin Sortable Buttons Screenshot
Related
I've set up user account signup and login pages following this tutorial and it all works great, except the pages have no formatting. I'm now looking for a simple drop in solution to improve the appearance of "templates/registration/login.html" and "templates/registration/signup.html". Someone recommended crispy forms which look great, and as the rest of my site uses Bootstrap 5, crispy-bootstrap5 looks ideal.
I'm struggling to implement crispy-bootstrap5 as I don't understand Django's inbuilt django.contrib.auth.forms nor forms in general, and can't find simple reproducible examples for crispy forms with signup.html and login.html. I've installed packages fine, but now don't know how to beautify login.html and signup.html from that tutorial:
{% extends 'base.html' %}
{% block title %}Sign Up{% endblock %}
{% block content %}
<h2>Sign up</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign Up</button>
</form>
{% endblock %}
I don't know where to go with this, but the docs for regular django-crispy links to a gist for an eg form, and the index.html {% load crispy_forms_tags %} and {% crispy form %}. I've put them in which mostly left the page unchanged except for messing up the formatting. I think I now need to modify class CustomUserCreationForm(UserCreationForm) in forms.py but I don't know how. I'm also reluctant to risk bigger problems by modifying Django's inbuilt functionalities I don't understand.
What steps need we take to get login.html and signup.html looking like bootstrap 5?
please follow bellow steps to use crispy_forms with bootstrap5:
1st step: Install crispy_forms form bootstrap 5
pip install crispy-bootstrap5
step 2: Add crispy_forms and crispy_bootstrap5 to installed apps
INSTALLED_APPS = (
...
"crispy_forms",
"crispy_bootstrap5",
...
)
step 3: add crispy form attr to settings file
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
CRISPY_TEMPLATE_PACK = "bootstrap5"
check here for details
to use crispy form in templates, add {% load crispy_forms_filters %} and {% load crispy_forms_tags %} on top of your sign up and login page.
and declare form as crispy i.e {{forms| crispy}} or field as {{ form.fieldname|as_crispy_field }}
I've a base.html file which has vertical and horizontal menu-bar:
Wherever I want to use that I just simply write:
{% extends 'base.html' %}
{% block content %}
//html code
{% endblock content %}
But I don't know how to use the same file base.html from templates directory in djando admin.
I want output like this:
What I Tried:
How to override and extend basic Django admin templates?
How do I correctly extend the django admin/base.html template?
Override Navbar in Django base admin page to be same as the base.html
I tried few other solution just don't want to increase the length of question and base.html file's code just has basic bootstrap, html code for menus.
I am new to Django, little explanation would be highly appreciated!
What you are looking is similar to nav-global.
Try this:
First create a folder in your templates folder as admin and create a html file(base_site.html) in the same folder
Assuming you have separate html file for menu-bars(Let's say the file is nav.html).
Write the below code in base_site.html:
{% extends 'admin/base.html' %}
{% block nav-global %}
{% include 'nav.html' %} #Your navigation html file
{% endblock %}
Unrelated to question: I found a git repo which will give you idea how to customize the django-admin menu.
You can just extend the admin's base template as
{% extends "admin/base.html" %}
For example:
{% extends "admin/base.html" %}
{% block sidebar %}
{{ block.super }}
<div>
<h1>Extra links</h1>
My extra link
</div>
{% endblock %}
Also, make sure that you have added the admin app to the INSTALLED_APPS
INSTALLED_APPS = [
# other apps,
'django.contrib.admin',
# other apps,
]
I had the same issue about a year and a half ago and I found a nice template loader on djangosnippets.org that makes this easy. It allows you to extend a template in a specific app, giving you the ability to create your own admin/index.html that extends the admin/index.html template from the admin app. Like this:
{% extends "admin:admin/index.html" %}
{% block sidebar %}
{{block.super}}
<div>
<h1>Extra links</h1>
My extra link
</div>
{% endblock %}
I need to edit the "Add Object" action in the admin. It needs to redirect the user to a custom cause the logic required for adding objects is too complex to be managed in the admin. So, how do I make this possible? i.e:
The picture shows a django-suit admin, but the question is the same. How can I make that button redirect to a custom url? Or, how can I create a similar button that redirects to a custom url (I could disable the default create and leave only the custom button).
Override change_list_template html, the block object-tools-items. It's where add button is placed.
class MyModelAdmin(admin.ModelAdmin):
change_list_template = 'change_list.html'
In your change_list.html
{% extends "admin/change_list.html" %}
{% load i18n admin_static admin_list %}
{% block object-tools-items %}
{% if has_add_permission %}
<li>
<a href="your/custom/url" class="addlink">
{% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
</a>
</li>
{% endif %}
{% endblock %}
You need to add your new html in any dir that is included on TEMPLATE_DIRS options. But, you should do it inside your model's app.
-app
-templates
-admin
change_list.html
Add above dir in TEMPLATE DIRS paths.
I have a very basic template (basic_template.html), and want to fill in the with data formatted using another partial template. The basic_template.html might contain several things formatted using the partial template.
How should I structure the code in views.py?
The reason I am doing this is that later on the will be filled using Ajax. Am I doing this right?
You can do:
<div class="basic">
{% include "main/includes/subtemplate.html" %}
</div>
where subtemplate.html is another Django template. In this subtemplate.html you can put the HTML that would be obtained with Ajax.
You can also include the template multiple times:
<div class="basic">
{% for item in items %}
{% include "main/includes/subtemplate.html" %}
{% endfor %}
</div>
You can do this using a block. Blocks are a Django Template tag which will override sections of a template you extend. I've included an example below.
basic_template.html
<body>
{% block 'body' %}
{% endblock %}
</body>
template you want to include: (i.e. example.html)
{% extends 'basic_template.html' %}
{% block 'body' %}
/* HTML goes here */
{% endblock %}
views.py:
return render_to_response(template='example.html', context, context_instance)
Doing this will load basic_template.html, but replace everything inside of {% block 'body' %} {% endblock %} in basic_template.html with whatever is contained within {% block 'body' %} {% endblock %}.
You can read more about blocks and template inheritance in the Django Docs
There are mainly 2 ways (2 easy ones)
1:
In base html put
{% include "myapp/sub.html" %}
And just write html code inside your sub.html file
2:
https://docs.djangoproject.com/en/dev/ref/templates/language/#template-inheritance
I just wanted to add differences of extend and include.
Both template and include can use models inserted in current app.
Template is for global usage by your any app. Include is for use in certain apps.
For ex: you want to insert Image Slider to your homepage and about page but nowhere else. You can create Slider app with its own model for convenience and import its model and include in that pages.
If you used template for this example, you would create 2 templates one with slider and everything else other template have.
I'm using separate template files to create "widgets" - HTML snippets that are displayed in a grid layout on the page. The main template includes the widget templates like this:
{% include "myapp/widgetA.html" %}
{% include "myapp/widgetB.html" %}
{% include "myapp/widgetC.html" %}
{% include "myapp/widgetD.html" %}
This works fine, but I want the user to be able to change the order that the widgets appear in. I will have the user's preferred ordering stored in a tuple, eg: ('widgetC', 'widgetB', 'widgetA', 'widgetD')
How can I handle this in the template?
You can iterate over the tuple in the template:
{% for widget in my_widgets %}
{% include widget %}
{% endfor %}
where my_widgets = ('myapp/widgetC.html', 'myapp/widgetB.html', 'myapp/widgetA.html', 'myapp/widgetD.html') in your view.