I want to add a checkbox in Django Admin that is not related to a field in my model.
Depending on the value of the checkbox, I want to do some extra actions.
class DeviceAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
#if checkbox:
# do_extra_actions()
super(DeviceAdmin, self).save_model(request, obj, form, change)
How to add this checkbox in the django admin form for my model Device and get the value in save_model function ?
You can first create a ModelForm with such extra checkbox:
class DeviceModelForm(forms.ModelForm):
extra_checkbox = forms.BooleanField(required=False)
Then you plug this into the DeviceAdmin and inspect its value:
class DeviceAdmin(admin.ModelAdmin):
form = DeviceModelForm
def save_model(self, request, obj, form, change):
if form.cleaned_data['extra_checkbox']:
# do_extra_actions()
pass
return super().save_model(request, obj, form, change)
Related
i defined a save_model in my UserAdmin to change object level permissions for users.
class UserAdmin(BaseUserAdmin):
def save_model(self, request, obj, form, change):
obj.save()
allprojects = Project.objects.all()
projects = obj.workingproject.all()
remove_perm("view_project", obj, allprojects)
assign_perm("view_project", obj, projects)
obj.save()
remove_perm and assign_perm are shortcuts from django-guardian, workingproject is a M2M field of user.
The problem: when selecting different projects and saving the permissions are not changed, but pressing the save button a second time makes the changes as wanted. What am i doing wrong?
Try this by overriding save_related
def save_related(self, request, form, formsets, change):
super(UserAdmin, self).save_related(request, form, formsets, change)
obj = form.instance
allprojects = Project.objects.all()
projects = obj.workingproject.all()
remove_perm("view_project", obj, allprojects)
assign_perm("view_project", obj, projects)
In save_related, Django is removing M2M that are already there and setting new ones. So changes doing in save_model and save will not reflect.
Am I interpreting the default behavior of the Django Admin site to not use the ModelManager's create method? If so, how would I get this behavior?
My model has a custom Model manager with bespoke create method.
Override the ModelAdmin.save_model() method:
class MyAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if change:
obj.save()
else:
new_obj = MyModel.objects.create(name=obj.name, ...)
obj.pk = new_obj.pk
class MyParentModelAdmin(admin.ModelAdmin):
def save_formset(self, request, form, formset, change):
if formset.model._meta.db_table=='MyInLIneModel':
In the debugger
formset.model = {ModelBase} <class 'my app.models.MyInLineModel'>
I am able to check by formset.model._meta.db_table which is 'MyInLineModel'.
I know this is not the right way.
can any one suggest a clean way to check the model name.
I have no idea why you do this but you can check it this way:
from your_app.models import SomeModel
class MyParentModelAdmin(admin.ModelAdmin):
def save_formset(self, request, form, formset, change):
if formset.model == SomeModel:
pass
I need to add some pre- and post-save logic to my ModelAdmin, but only when the user submitted the form via the 'Save and continue editing' button and not the 'Save' button. How can I do this?
Just like overriding the normal save method, you need to override the save_model() function in your ModelAdmin, which includes the request object. From the request object you can get the POST object, which will include a '_continue' key if the user clicked the 'Save and continue button'. Example:
class MyAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, changed):
if '_continue' in request.POST:
# add your code here
return super(ServerAdmin, self).change_view(request, obj, form, changed)
whenever I save a model in my Admin interface, it displays the usual "successfully saved message."
However, I want to know if it's possible to customize this message because I have a situation where I want to warn the user about what he just saved and the implications of these actions.
class PlanInlineFormset(forms.models.BaseInlineFormset):
def clean(self):
### How can I detect the changes?
### (self.changed_data doesn't work because it's an inline)
### and display what he/she just changed at the top AFTER the successful save?
class PlanInline(admin.TabularInline):
model = Plan
formset = PlanInlineFormset
Django (> version 1.2) uses the messages framework for admin messages. You can add additional messages using that interface. Here's an example:
from django.contrib import messages
class SomeModelAdmin(admin.ModelAdmin):
# your normal ModelAdmin stuff goes here
def save_model(self, request, obj, form, change):
# add an additional message
messages.info(request, "Extra message here.")
super(SomeModelAdmin, self).save_model(request, obj, form, change)
To detect changes to the object being saved, you should be to override the save_model method of ModelAdmin, and compare the object the method is passed to the version currently in the database. To do this in the case of inlines, you can override the save_formset method. A possible approach might look like (untested code):
class SomeModelAdmin(admin.ModelAdmin):
# your normal ModelAdmin stuff goes here
def save_formset(self, request, form, formset, change):
if not change:
formset.save()
else:
instances = formset.save(commit=False)
for instance in instances:
try:
# if you've got multiple types of inlines
# make sure your fetching from the
# appropriate model type here
old_object = SomeOtherModel.get(id=instance.id)
except SomeOtherModel.DoesNotExist:
continue
if instance.field_x != old_object.field_x:
messages.info(request, "Something Changed")
instance.save()
formset.save_m2m()
If you're using Django 1.2 or newer, the messages framework may hold the answer.
http://docs.djangoproject.com/en/dev/ref/contrib/messages/