Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 2 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,29 +105,17 @@ class PersonAdmin(ReverseModelAdmin):

#### Do not allow deletion

django-reverse-admin uses the standard features of in-line forms (Stacked and Tabular). When used in the ReverseAdmin co-text, it releases the option to delete the associated object.

To remove this option (thus making the object unable to be deleted), it is necessary to add the admin_class inheriting from one of the native resources (Stacked and Tabular). Example:
To prevent deletion of the inlined object, use the `can_delete` option:

```py
from .forms import CustomBusinessAddrForm


class BarInline(admin.StackedInline):
model = Address

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


class PersonAdmin(ReverseModelAdmin):
inline_type = 'tabular'
inline_reverse = [
'business_addr',
{
'field_name': 'home_addr',
'fields': ('zip_code',),
'admin_class': BarInline
'can_delete': False,
}
]
```
Expand Down
10 changes: 7 additions & 3 deletions django_reverse_admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,15 @@ def reverse_inlineformset_factory(parent_model,
form=ModelForm,
fields=None,
exclude=None,
formfield_callback=lambda f: f.formfield()):
formfield_callback=lambda f: f.formfield(),
**kwargs):

if fields is None and exclude is None:
related_fields = [f for f in model._meta.get_fields() if
(f.one_to_many or f.one_to_one or f.many_to_many) and f.auto_created and not f.concrete]
fields = [f.name for f in model._meta.get_fields() if f not in
related_fields] # ignoring reverse relations
kwargs = {
defaults = {
'form': form,
'formfield_callback': formfield_callback,
'formset': ReverseInlineFormSet,
Expand All @@ -83,7 +84,8 @@ def reverse_inlineformset_factory(parent_model,
'exclude': exclude,
'max_num': 1,
}
FormSet = modelformset_factory(model, **kwargs)
defaults.update(**kwargs)
FormSet = modelformset_factory(model, **defaults)
FormSet.parent_fk_name = parent_fk_name
return FormSet

Expand Down Expand Up @@ -129,12 +131,14 @@ def get_formset(self, request, obj=None, **kwargs):
exclude.extend(non_editable_fields)
# but need exclude to be None if result is an empty list
exclude = exclude or None
can_delete = self.can_delete and self.has_delete_permission(request, obj)

defaults = {
"form": self.form,
"fields": fields,
"exclude": exclude,
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
"can_delete": can_delete,
}
kwargs.update(defaults)
return reverse_inlineformset_factory(self.parent_model,
Expand Down
11 changes: 11 additions & 0 deletions tests/polls/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from polls.models import Address
from polls.models import NonInlinePerson
from polls.models import Person
from polls.models import PersonNoDeleteAddress
from polls.models import PersonWithAddressNonId
from polls.models import PersonWithTwoAddresses
from polls.models import PhoneNumber
Expand Down Expand Up @@ -41,6 +42,15 @@ def get_readonly_fields(self, request, obj=None):
return self.readonly_fields


class PersonNoDeleteAddressAdmin(PersonAdmin):
inline_reverse = [
('home_addr', {
'fields': ['street', 'city', 'state', 'zipcode'],
'can_delete': False,
}),
]


class PersonWithAddressNonIdAdmin(ReverseModelAdmin):
list_display = ('name', 'home_addr')

Expand Down Expand Up @@ -74,6 +84,7 @@ class AddressAdmin(admin.ModelAdmin):


admin.site.register(Person, PersonAdmin)
admin.site.register(PersonNoDeleteAddress, PersonNoDeleteAddressAdmin)
admin.site.register(PersonWithAddressNonId, PersonWithAddressNonIdAdmin)
admin.site.register(PersonWithTwoAddresses, PersonWithTwoAddressesAdmin)
admin.site.register(PhoneNumber, PhoneNumberAdmin)
Expand Down
4 changes: 4 additions & 0 deletions tests/polls/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ def __str__(self):
return self.name


class PersonNoDeleteAddress(Person):
pass


class PersonWithAddressNonId(TemporalBase):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255)
Expand Down