====== Django Admin ======
===== Basic =====
To create a super user: ''$ python manage.py createsuperuser''
==== Registrar clases ====
from django.contrib import admin
from catalog.models import Author, Genre, Book, BookInstance
admin.site.register(Book)
admin.site.register(Author)
admin.site.register(Genre)
admin.site.register(BookInstance)
**También puedes hacerlo con clases** (permite añadir varios admins):
class CoopolisAdmin(AdminSite):
site_header = "Coópolis Backoffice"
site_title = "Coópolis backoffice"
index_title = "Benvingut!"
coopolis_admin_site = CoopolisAdmin(name='coopolis_admin')
coopolis_admin_site.register(User)
coopolis_admin_site.register(Project)
coopolis_admin_site.register(Course)
coopolis_admin_site.register(Activity)
Las url estarían en ''coopolis_admin_site.urls'':
urlpatterns = [
path('entity-admin/', admin.site.urls),
path('event-admin/', coopolis_admin_site.urls),
]
Puedes registrar también ModelAdmins:
class AuthorAdmin(admin.ModelAdmin):
pass
admin.site.register(Author, AuthorAdmin)
O con un decorador:
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
pass
==== List views ====
Indicar los **campos** que se verán:
class AuthorAdmin(admin.ModelAdmin):
list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
Los **ManyToMany** no se verán en la lista. Aún así podemos sacar un campo como tal:
def display_genre(self):
"""Create a string for the Genre. This is required to display genre in Admin."""
return ', '.join(genre.name for genre in self.genre.all()[:3])
display_genre.short_description = 'Genre'
Los filtros pueden indicarse también:
class BookInstanceAdmin(admin.ModelAdmin):
list_filter = ('status', 'due_back')
:!: **Important**:_ To tell Django we want to perform a join instead of fetching the names of the categories one by one,we can use list_select_related
@admin.register(models.Product)
class ProductAdmin(admin.ModelAdmin):
list_display = (
'id',
'name',
'category',
)
list_select_related = (
'category',
)
=== Add a link into the list ===
from django.contrib import admin
from django.utils.html import format_html
class CourseAdmin(admin.ModelAdmin):
list_display = ('title', 'my_url_field',)
def my_url_field(self, obj):
return format_html('%s' % ('http://url-to-prepend.com/', obj.title, obj.title))
my_url_field.allow_tags = True
my_url_field.short_description = 'Column description'
==== Changing the layout ====
To put several fields in a row:
class AuthorAdmin(admin.ModelAdmin):
list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
fields = ['first_name', 'last_name', ('date_of_birth', 'date_of_death')]
Add fieldsets (sections):
@admin.register(BookInstance)
class BookInstanceAdmin(admin.ModelAdmin):
list_filter = ('status', 'due_back')
fieldsets = (
(None, {
'fields': ('book', 'imprint', 'id')
}),
('Availability', {
'fields': ('status', 'due_back')
}),
)
You can do this by declaring inlines, of type TabularInline (horizonal layout) or StackedInline (vertical layout, just like the default model layout).
class BooksInstanceInline(admin.TabularInline):
model = BookInstance
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'display_genre')
inlines = [BooksInstanceInline]
===== Admin templates =====
==== Overriding them ====
* https://docs.djangoproject.com/en/2.0/ref/contrib/admin/#admin-overriding-templates
===== JS y CSS en el Admin =====
==== Usando jQuery en el Django Admin ====
(function($) {
// < start of closure
// within this block, $ = django.jQuery
$(document).ready(function() {
// Your JavaScript
});
})(django.jQuery);
==== Add static snippets ====
# admin.py
class MyModelAdmin(admin.ModelAdmin):
# admin additions
class Media:
css = {
"all": ("css/my_style.css",)
}
js = ("js/my_script.js",)
===== Gotchas =====
==== Basic ====
=== Change the title and pages ===
admin.site.site_header = "UMSRA Admin"
admin.site.site_title = "UMSRA Admin Portal"
admin.site.index_title = "Welcome to UMSRA Researcher Portal"
=== Change the name of a class in the Admin ===
class Category(models.Model):
...
class Meta:
verbose_name_plural = "Categories"
=== Unregister a class ===
from django.contrib.auth.models import Group
admin.site.unregister(Group)
=== Add new page to the admin ===
class CourseAdmin(admin.ModelAdmin):
list_display = ('title', 'my_url_field',)
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path(
r'attendee-list/',
self.admin_site.admin_view(self.attendee_list),
name='attendee-list',
),
]
return custom_urls + urls
def my_url_field(self, obj):
return format_html('Llista d\'assistencia' % reverse('admin:attendee-list'))
my_url_field.allow_tags = True
my_url_field.short_description = 'Column description'
def attendee_list(self, request):
import weasyprint
import django.template.loader as loader
temp = loader.get_template('admin/attendee_list.html')
html = temp.render()
pdf = weasyprint.HTML(string=html.encode('utf-8'))
response = HttpResponse(pdf.write_pdf(), content_type='application/pdf')
# response['Content-Disposition'] = 'attachment; filename="llista_assistencia.pdf"'
response['Content-Disposition'] = 'filename="llista_assistencia.pdf"'
return response
=== Dynamically hide fields ===
class BookAdmin(admin.ModelAdmin):
list_display = ("pk", "get_title_or_nothing")
def get_form(self, request, obj=None, **kwargs):
if obj.type == "1":
self.exclude = ("title", )
form = super(BookAdmin, self).get_form(request, obj, **kwargs)
return form