Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
wiki2:python:django:admin [2018/11/09 10:35] alfred [Registrar clases] |
wiki2:python:django:admin [2020/05/09 09:25] (actual) |
||
|---|---|---|---|
| Línea 37: | Línea 37: | ||
| path('event-admin/', coopolis_admin_site.urls), | path('event-admin/', coopolis_admin_site.urls), | ||
| ] | ] | ||
| + | </code> | ||
| + | |||
| + | Puedes registrar también ModelAdmins: | ||
| + | <code> | ||
| + | class AuthorAdmin(admin.ModelAdmin): | ||
| + | pass | ||
| + | |||
| + | admin.site.register(Author, AuthorAdmin) | ||
| + | </code> | ||
| + | |||
| + | O con un decorador: | ||
| + | <code> | ||
| + | @admin.register(Book) | ||
| + | class BookAdmin(admin.ModelAdmin): | ||
| + | pass | ||
| + | </code> | ||
| + | |||
| + | ==== List views ==== | ||
| + | Indicar los **campos** que se verán: | ||
| + | <code> | ||
| + | class AuthorAdmin(admin.ModelAdmin): | ||
| + | list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death') | ||
| + | </code> | ||
| + | |||
| + | Los **ManyToMany** no se verán en la lista. Aún así podemos sacar un campo como tal: | ||
| + | <code> | ||
| + | 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' | ||
| + | </code> | ||
| + | |||
| + | Los filtros pueden indicarse también: | ||
| + | <code> | ||
| + | class BookInstanceAdmin(admin.ModelAdmin): | ||
| + | list_filter = ('status', 'due_back') | ||
| + | </code> | ||
| + | |||
| + | :!: **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 | ||
| + | <code> | ||
| + | @admin.register(models.Product) | ||
| + | class ProductAdmin(admin.ModelAdmin): | ||
| + | list_display = ( | ||
| + | 'id', | ||
| + | 'name', | ||
| + | 'category', | ||
| + | ) | ||
| + | list_select_related = ( | ||
| + | 'category', | ||
| + | ) | ||
| + | </code> | ||
| + | |||
| + | === Add a link into the list === | ||
| + | <code python> | ||
| + | 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('<a href="%s%s">%s</a>' % ('http://url-to-prepend.com/', obj.title, obj.title)) | ||
| + | my_url_field.allow_tags = True | ||
| + | my_url_field.short_description = 'Column description' | ||
| + | </code> | ||
| + | ==== Changing the layout ==== | ||
| + | To put several fields in a row: | ||
| + | <code> | ||
| + | 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')] | ||
| + | </code> | ||
| + | |||
| + | Add fieldsets (sections): | ||
| + | <code> | ||
| + | @admin.register(BookInstance) | ||
| + | class BookInstanceAdmin(admin.ModelAdmin): | ||
| + | list_filter = ('status', 'due_back') | ||
| + | | ||
| + | fieldsets = ( | ||
| + | (None, { | ||
| + | 'fields': ('book', 'imprint', 'id') | ||
| + | }), | ||
| + | ('Availability', { | ||
| + | 'fields': ('status', 'due_back') | ||
| + | }), | ||
| + | ) | ||
| + | </code> | ||
| + | |||
| + | You can do this by declaring inlines, of type TabularInline (horizonal layout) or StackedInline (vertical layout, just like the default model layout). | ||
| + | <code> | ||
| + | class BooksInstanceInline(admin.TabularInline): | ||
| + | model = BookInstance | ||
| + | |||
| + | @admin.register(Book) | ||
| + | class BookAdmin(admin.ModelAdmin): | ||
| + | list_display = ('title', 'author', 'display_genre') | ||
| + | inlines = [BooksInstanceInline] | ||
| + | </code> | ||
| + | |||
| + | ===== 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 ==== | ||
| + | <code> | ||
| + | (function($) { | ||
| + | // < start of closure | ||
| + | // within this block, $ = django.jQuery | ||
| + | $(document).ready(function() { | ||
| + | // Your JavaScript | ||
| + | }); | ||
| + | })(django.jQuery); | ||
| + | </code> | ||
| + | |||
| + | ==== Add static snippets ==== | ||
| + | <code> | ||
| + | # admin.py | ||
| + | class MyModelAdmin(admin.ModelAdmin): | ||
| + | # admin additions | ||
| + | |||
| + | class Media: | ||
| + | css = { | ||
| + | "all": ("css/my_style.css",) | ||
| + | } | ||
| + | js = ("js/my_script.js",) | ||
| </code> | </code> | ||
| ===== Gotchas ===== | ===== Gotchas ===== | ||
| Línea 63: | Línea 194: | ||
| admin.site.unregister(Group) | admin.site.unregister(Group) | ||
| </code> | </code> | ||
| + | |||
| + | === Add new page to the admin === | ||
| + | <code python> | ||
| + | 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('<a href="%s" target="_new">Llista d\'assistencia</a>' % 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 | ||
| + | </code> | ||
| + | |||
| + | === Dynamically hide fields === | ||
| + | <code> | ||
| + | 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 | ||
| + | </code> | ||
| + | |||
| + | |||