How can i change the display label Auth in the Django admin dashboard to Authentication?
There is currently no easy/elegant way to do this. Customisable app-labelling has been a sore point for some time. You can override admin/index.html and inject some javascript code to change the labelling. Note that you could also change admin.site.index_template to something like "admin/my_index.html", which can then use {% extends "admin/index.html" %} to keep things DRYer.
Of course there are other areas in the admin that "Auth" will appear also, such in "admin/app_index.html", the breadcrumbs, etc...
I imagine if your overwriting admin/index.html you could hard code the logic in the template instead of any javascript:
<caption><a href="{{ app.app_url }}" class="section">
{% ifequal app.name "Auth" %}
{% trans 'Authentication' %}
{% else %}
{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}
{% endifequal %}
</a></caption>
Related
As we known, there is an "Add" button in each model in django admin site. How can I change the name of it into like "Add Student" to make it customerized.
I have found the add button in the template
{% if has_add_permission %}
{% url cl.opts|admin_urlname:'add' as add_url %}
<el-button size="small" type="primary" icon="el-icon-plus" data-name="add_item"
url="{% add_preserved_filters add_url is_popup to_field %}">
{% trans 'Add' %}
</el-button>
{% endif %}
I change the "{% trans 'Add' %}" and the button's name can be changed, but all the models page Add button are changed. Is there any way to change it just for one model?
Not looking at your code is hard to give an exact answer but you can override any admin template by extending it.
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing-an-admin-template
Below is an example to extend change_form similarly you can do for any admin form - just find where this add button is and extend it.
{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}
{% block object-tools-items %}
CUSTOM_CODE
{% endblock %}
There might be possibility to do via python code as well but need to see code for it
My django admin interface looks like this:
Now I would like to add a view which does not correspond to a model.
I could overwrite the template of above page and add a custom link. But I think this would look ugly.
Example for overwriting admin/index.html:
{% extends "admin/index.html" %}
{% block content %}
{{ block.super }}
<div class="app-sonstiges module">
....
</div>
{% endblock %}
But maybe there is an official way to do add a custom view to the admin interface?
In my case I want to provide a form which can execute tcptraceroute to a remote server. The admin of my app needs this.
I used the same html tags. Now the link "tcptraceroute" looks nice, but unfortunately the messages moved down:
Is there a way to get a custom part like "Sontiges ... tcptraceroute" like in the screenshot, without moving the latest actions down?
Here is how the html structure looks like. My <div class="app-sonstiges"> is below content-main:
You have 3 options here:
Using third-party packages which provide menu
This is pretty straight forward, there are some good packages out there which support menu for admin, and some way to add your item to the menu.
An example of a 3rd party package would be django-admin-tools. The drawback is that it is a bit hard to learn. Another option would be to use django-adminplus but at the time of writing this, it does not support Django 2.2.
Hacking with django admin templates
You can always extend admin templates and override the parts you want, as mentioned in #Sardorbek answer, you can copy some parts from admin template and change them the way you want.
Using custom admin site
If your views are supposed to only action on admin site, then you can extend adminsite (and maybe change the default), beside from adding links to template, you should use this method to define your admin-only views as it's easier to check for permissions this way.
Considering you already extended adminsite, now you can use the previous methods to add your link to template, or even extend get_app_list method, example:
class MyAdminSite(admin.AdminSite):
def get_app_list(self, request):
app_list = super().get_app_list(request)
app_list += [
{
"name": "My Custom App",
"app_label": "my_test_app",
# "app_url": "/admin/test_view",
"models": [
{
"name": "tcptraceroute",
"object_name": "tcptraceroute",
"admin_url": "/admin/test_view",
"view_only": True,
}
],
}
]
return app_list
You can also check if current staff user can access to module before you show them the links.
It will look like this at then end:
Problem here that your div is not inside main-content. I suggest extending admin/index.html
Put in app/templates/admin/index.html
{% extends "admin/index.html" %}
{% load i18n static %}
{% block content %}
<div id="content-main">
{% if app_list %}
{% for app in app_list %}
<div class="app-{{ app.app_label }} module">
<table>
<caption>
{{ app.name }}
</caption>
{% for model in app.models %}
<tr class="model-{{ model.object_name|lower }}">
{% if model.admin_url %}
<th scope="row">{{ model.name }}</th>
{% else %}
<th scope="row">{{ model.name }}</th>
{% endif %}
{% if model.add_url %}
<td>{% trans 'Add' %}</td>
{% else %}
<td> </td>
{% endif %}
{% if model.admin_url %}
{% if model.view_only %}
<td>{% trans 'View' %}</td>
{% else %}
<td>{% trans 'Change' %}</td>
{% endif %}
{% else %}
<td> </td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
{% endfor %}
<!-- here you could put your div -->
<div class="app-sonstiges module">
....
</div>
<!-- here you could put your div -->
{% else %}
<p>{% trans "You don't have permission to view or edit anything." %}</p>
{% endif %}
</div>
{% endblock %}
The another approach is to add custom app to app_list. But it is far more ugly. So I suggest overriding template.
I assume you are overriding get_urls in AdminSite.
If you need a custom page to handle user input (from form), you may want to give django-etc 1.3.0+ a try:
from etc.admin import CustomModelPage
class MyPage(CustomModelPage):
title = 'My custom page' # set page title
# Define some fields you want to proccess data from.
my_field = models.CharField('some title', max_length=10)
def save(self):
# Here implement data handling.
super().save()
# Register the page within Django admin.
MyPage.register()
I would like to create a product that will be available in Shopify's storefront but only accessible for the shop administrator. Is there a way to identify if the current user is an admin via liquid? Or is there any other solution for this. Thanks!
If you're signed in as an admin, when rendering the {{ content_for_header }} include, it will contain some JavaScript to push the page content down to make room for the Shopify admin bar.
We can utilize capture to store the {{ content_for_header }} code as a liquid variable and then use the contains operator to check if admin_bar_iframe exists in the variable.
{% capture CFH %}{{ content_for_header }}{% endcapture %}{{ CFH }}
{% if CFH contains 'admin_bar_iframe' %}
{% assign admin = true %}
{% endif %}
{% if admin %}
<!-- User is an admin -->
{% else %}
<!-- User is not an admin -->
{% endif %}
Note: I've noticed that the Shopify admin bar doesn't populate at all times (I think its a bug). If your Shopify admin bar is not populating on your instance this will not work.
Just figured out this method that works. (Basically the same thing as the old method, just another way around!)
Detecting logged in admin viewing site:
{% if content_for_header contains 'adminBarInjector' %}
<script>
console.log("You're a logged in admin viewing the site!");
</script>
{% endif %}
Detecting admin in design mode:
{% if content_for_header contains 'designMode' %}
<script>
console.log("You're an admin in design mode!");
</script>
{% endif %}
Another approach would be to use Customer Accounts. Liquid provides a {{ customer }} object, which is only present when a user (customer) is logged in.
You can add a specific tag to an admin user and use liquid to verify if a tag is present:
{% if customer.tags contains "admin" %}
And of course you need to identify your product as 'admin-only', for example using tags:
{% if customer.tags contains "admin" and product.tags contains "admin" %}
<!-- render product -->
{% else %}
<!-- do nothing -->
{% endif %}
EDIT: This seems not to be working anymore since an update to Shopify.
I know this is late, but here is what I've used and it has worked correctly in my testing. This is adapted from the previous answers, but allows use for Customise Theme options, etc.
{% capture CFH %}{{ content_for_header }}{% endcapture %}{{ CFH }}
{% assign isAdmin = true %}
{% if CFH contains '"__st"' %}
{% if CFH contains 'admin_bar_iframe' %}{% else %}
{% assign isAdmin = false %}
{% endif %}
{% endif %}
This is a more complete version of that provided by kyle.stearns above (I can't comment on it because new). One of the main instances where admin bar doesn't load is when previewing themes. Here is the amended code which I've used (updated June 2018 - as Shopify edited the way we preview themes):
{% capture CFH %}{{ content_for_header }}{% endcapture %}
{% if CFH contains 'admin_bar_iframe' %}
{% assign admin = true %}
{% elsif CFH contains 'preview_bar_injector-' %}
{% assign admin = true %}
{% endif %}
{% if admin %}
<!-- User is an admin -->
<script>
alert ("do some work");
</script>
{% else %}
<!-- User is not an admin -->
<script>
alert ("please buy some stuff");
</script>
{% endif %}
If you're using Plus then you also have access to the User via api.
I know this is an old question, but it still shows on top in google searches.
There's now a much better way.
Using liquid:
{% if request.design_mode %}
<!-- This will only render in the theme editor -->
{% endif %}
Using javascript:
if (Shopify.designMode) {
// This will only render in the theme editor
}
Source: shopify.dev
Currently there isn't. You could perhaps try inspecting cookies and stuff to see if there's some identifying information that would let you know if the user is an admin, but it would be fragile.
This would also require rendering the items, but hiding them via CSS. Then you'd show them using JS after you've run your checks.
As stated, this would probably be really fragile.
I want to have a save button on top of django admin change list page. It seems that django don't have this functionality built-in. The save_on_top option only controls behavior on change form page. Any suggestion is welcome.
In Django 3 (and maybe earlier, not sure) in your custom admin form add save_on_top = True
class MyAdmin(admin.ModelAdmin):
save_on_top = True
First, you need a way to extend the template found at django/contrib/admin/templates/admin/change_list.html. If you don't already know how to do that, check out this answer and this answer.
Next, you need to create your own change_list.html template and put code similar to the following in it. For the sake of simplicity, I've included inline CSS. However, this is bad practice, so you should not do it. Assuming you move the CSS to an external file, you won't need to load admin_static. Lastly, the extends line that you use might not be exactly the same as what I've shown here.
{% extends "contrib/admin/templates/admin/change_list.html" %}
{% load i18n admin_static %}
{% block result_list %}
{% if cl.formset and cl.result_count %}
<div style="border-bottom: 1px solid #ccc; background: white url({% static "admin/img/nav-bg.gif" %}) 0 180% repeat-x; overflow: hidden;">
<p>
<input type="submit" name="_save" class="default" value="{% trans 'Save' %}"/>
</p>
</div>
{% endif %}
{{ block.super }}
{% endblock %}
The {% if %} tag and the <input> tag inside of it is from django/contrib/admin/templates/admin/pagination.html.
The CSS is based on the CSS for #changelist .paginator and is found in django/contrib/admin/static/admin/css/changelists.css.
If you don't mind having pagination links at the top of the page as well, you can do it with a few lines of template code, worksforme in Django 2.0.
Create my_app/templates/admin/my_app/my_model/change_list.html:
{% extends "admin/change_list.html" %}
{% load admin_list %}
{% block result_list %}
{% pagination cl %}
{{ block.super }}
{% endblock %}
This will render the pagination and the save button:
Could benefit from a line or two of CSS, though...
I want to change the words "Site administration" to something else under the admin page. I tried a couple of grep commands but I couldn't find the right template:
hobbes3#hobbes3 ~/Sites/mysite/site-packages/django/contrib/admin/templates $ grep -ri "site administration" .
hobbes3#hobbes3 ~/Sites/mysite/site-packages/django/contrib/admin/templates $ grep -ri "administration" .
./admin/base_site.html:<h1 id="site-name">{% trans 'Django administration' %}</h1>
hobbes3#hobbes3 ~/Sites/mysite/site-packages/django/contrib/admin/templates $ grep -ri "site" .
./admin/404.html:{% extends "admin/base_site.html" %}
./admin/500.html:{% extends "admin/base_site.html" %}
./admin/500.html:<p>{% trans "There's been an error. It's been reported to the site administrators via e-mail and should be fixed shortly. Thanks for your patience." %}</p>
./admin/auth/user/change_password.html:{% extends "admin/base_site.html" %}
./admin/base_site.html:{% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %}
./admin/base_site.html:<h1 id="site-name">{% trans 'Django administration' %}</h1>
./admin/change_form.html:{% extends "admin/base_site.html" %}
./admin/change_form.html: {% if has_absolute_url %}<li>{% trans "View on site" %}</li>{% endif%}
./admin/change_list.html:{% extends "admin/base_site.html" %}
./admin/delete_confirmation.html:{% extends "admin/base_site.html" %}
./admin/delete_selected_confirmation.html:{% extends "admin/base_site.html" %}
./admin/edit_inline/stacked.html: {% if inline_admin_form.show_url %}{% trans "View on site" %}{% endif %}
./admin/edit_inline/tabular.html: {% if inline_admin_form.show_url %}{% trans "View on site" %}{% endif %}
./admin/index.html:{% extends "admin/base_site.html" %}
./admin/invalid_setup.html:{% extends "admin/base_site.html" %}
./admin/login.html:{% extends "admin/base_site.html" %}
./admin/object_history.html:{% extends "admin/base_site.html" %}
./admin/object_history.html: <p>{% trans "This object doesn't have a change history. It probably wasn't added via this admin site." %}</p>
./registration/logged_out.html:{% extends "admin/base_site.html" %}
./registration/logged_out.html:<p>{% trans "Thanks for spending some quality time with the Web site today." %}</p>
./registration/password_change_done.html:{% extends "admin/base_site.html" %}
./registration/password_change_form.html:{% extends "admin/base_site.html" %}
./registration/password_reset_complete.html:{% extends "admin/base_site.html" %}
./registration/password_reset_confirm.html:{% extends "admin/base_site.html" %}
./registration/password_reset_done.html:{% extends "admin/base_site.html" %}
./registration/password_reset_email.html:{% blocktrans %}You're receiving this e-mail because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
./registration/password_reset_email.html:{% trans "Thanks for using our site!" %}
./registration/password_reset_email.html:{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
./registration/password_reset_form.html:{% extends "admin/base_site.html" %}
Am I looking at the wrong place or something?
EDIT:
After some digging, I think it has something to do with the {% block content_title %}{% endblock %} inside base.html...
EDIT 2:
Here is a screenshot of the words "Site administration" that I am talking about on the admin's homepage.
Give the docs a read; admin docs and customising look and feel
Its a simple case of setting up a template for the admin which overwrites the default;
The template to customize is admin/index.html. (Do the same as with admin/base_site.html in the previous section -- copy it from the default directory to your custom template directory.) Edit the file, and you'll see it uses a template variable called app_list. That variable contains every installed Django app. Instead of using that, you can hard-code links to object-specific admin pages in whatever way you think is best. Again, don't worry if you can't understand the template language -- we'll cover that in more detail in Tutorial 3.
I went through all the tutorials in the Django docs I linked to a couple of weeks back but can't find an example of a custom Admin template, but this site looks like it'll certainly help you understand it;
http://blog.montylounge.com/2009/07/5/customizing-django-admin-branding/
The title _("Site administration") is defined the sites.py file under contrib/admin/. Either you change that string there and have to remember to change it every time you upgrade Django (not recommended) or you override the base_site.html template and add the title manually there.
Thought I'd add a more up-to-date reference for this old question, seeing as it's still viewed and active, and I find the docs overwhelmingly thorough.
Subclass AdminSite to rename template variables
myapp/admin.py
from django.contrib.admin import AdminSite
from .models import MyModel
class MyAdminSite(AdminSite):
# this is the variable you asked about
site_header = 'Monty Python administration'
admin_site = MyAdminSite(name='myadmin')
admin_site.register(MyModel)
myproject/urls.py
from django.conf.urls import url
from myapp.admin import admin_site
urlpatterns = [
url(r'^myadmin/', admin_site.urls),
]
Ref: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#customizing-adminsite
The properties you can customise on your admin_site are:
site_header, site_title, site_url, index_title, index_template,
app_index_template, empty_value_display, login_template, login_form,
logout_template, password_change_template, password_change_done_template
Extend admin templates
In addition, you can extend the default admin templates:
{% extends "admin/change_form.html" %}
{% block object-tools-items %}
<p>
Let's nuke this block and add custom content!
The rest of the default change_form template remains the same.
</p>
{% endblock %}
Ref: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-admin-templates
Another example of this is adding a custom stylesheet:
{% extends "admin/base.html" %}
{% load static %}
{% block extrahead %}
<link rel="stylesheet" href="{% static "my-app/admin-custom.css" %}">
{% endblock %}
This shows an override for all instances of change_form, but you can also override the templates in individual ModelAdmin and TabularInline, etc classes.
There's a fair bit of inheritance going on throughout django-admin, so installing Django Debug Toolbar is very helpful for figuring out what to extend (and where your override should be placed in the templates directory).