douglasmiranda / django-admin-bootstrap

Responsive Theme for Django Admin With Sidebar Menu
MIT License
879 stars 233 forks source link

Last inline not displayed, if has_add_permission returns False #132

Open misli opened 5 years ago

misli commented 5 years ago

Lets have following simple test application: models.py:

from django.db import models

class Parent(models.Model):
    name = models.CharField(max_length=20)

class Child(models.Model):
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE)
    name = models.CharField(max_length=20)

admin.py:

from django.contrib import admin

from .models import Child, Parent

class ChildInlineAdmin1(admin.TabularInline):
    model = Child

    def has_add_permission(self, request):
        return False

class ChildInlineAdmin2(admin.TabularInline):
    model = Child

class ParentAdmin(admin.ModelAdmin):
    inlines = (ChildInlineAdmin1, ChildInlineAdmin2)

admin.site.register(Parent, ParentAdmin)

The first Inline admin doesn't show the last child.

misli commented 5 years ago

screenshot

misli commented 5 years ago

I've found that it only happens with Django 2. Following patch works for me, but it is obviously not backwards compatible:

--- bootstrap_admin/templates/admin/edit_inline/tabular.html.orig    2018-11-29 20:54:55.766817156 +0100
+++ bootstrap_admin/templates/admin/edit_inline/tabular.html 2018-11-29 21:11:30.891857420 +0100
@@ -29,7 +29,7 @@
             {% if inline_admin_form.form.non_field_errors %}
               <tr><td colspan="{{ inline_admin_form|cell_count }}">{{ inline_admin_form.form.non_field_errors }}</td></tr>
             {% endif %}
-            <tr class="form-row {% cycle "row1" "row2" %} {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}{% if forloop.last %} empty-form{% endif %}"
+            <tr class="form-row {% cycle "row1" "row2" %} {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}{% if forloop.last and inline_admin_formset.has_add_permission %} empty-form{% endif %}"
                  id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
             <td class="original">
               {% if inline_admin_form.original or inline_admin_form.show_url %}<p>
jasonbodily commented 4 years ago

Same concerns here.

from django.contrib import admin
from app.models import Tags

class TagsInline(admin.TabularInline):
    model = Tags
    fields = ('created_at', 'updated_at')
    extra = 0

    def has_add_permission(self, request, obj=None):
        return False

    def has_delete_permission(self, request, obj=None):
        return False

I would expect that returning False on the has_add_permission method would only remove the ability to create instances. Instead it also hides entries of the queryset. When I remove bootstrap-admin from my projects dependencies, those query entries show. Also, this behavior does not occur in Django 1.11 with admin-bootstrap 0.3.9

Environment:

Thanks for your work on this repo

Megajoe17 commented 3 years ago

Adding condition "and inline_admin_formset.has_add_permission" to template is fixing problem:

/templates/admin/edit_inline/tabular.html

<tr class="form-row {% cycle "row1" "row2" %} {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}{% if forloop.last and inline_admin_formset.has_add_permission %} empty-form{% endif %}"