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
Related
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)
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
I have a posting object that can be either accessed in the website or the admin panel. In both, the user is automatically assigned to the post when the user posts it. In the website area, it works fine. However, it does not work in the admin area. First, I tried just having the form input there. When I try to save the object and leave the input blank, it tells me the form has no value. Then, trying to see if I just put in a random value and see if it was overwritten, I did that. However, that random value was not overwritten with the current user. If I excluded the field, when I try to save the model I get an Integrity error saying the field author 'may not be NULL', so I'm assuming my save_model() function is not firing right at all. Now the code I'm using for this I've seen all over the internet and people claim for it to work, I don't know if it's just broken now or what. Here's my code:
from django.contrib import admin
from posting.models import Posting, Categories
class PostingAdmin(admin.ModelAdmin):
list_display = ("title","author", "article","date")
exclude = ('author',)
fieldsets = (
(None, {
'fields': ('title',)
}),
('Body', {
'fields': ('article',)
}),
)
def save_model(self,request,form,obj,change):
print 'ENTERING SAVE_MODEL FUNCTION'
if not change:
obj.author = request.user
print 'OBJ.AUTHOR:' + str(obj.author)
obj.save()
print "EXITING SAVE_MODEL FUNCTION"
admin.site.register(Posting, PostingAdmin)
I added this for information only as I came across this post which made me look deeper for an issue I was having that was similar...
To pre-populate an admin field in Django 1.11 from "request" data, see below example of a models "user" field being pre-populated with the logged in user:
admin.py
class PostingAdmin(admin.ModelAdmin):
def get_changeform_initial_data(self, request):
return {'user': request.user}
This populates the field when initially adding a new "Posting Admin" (model instance) before it has been saved for the first time.
You could override the ModelAdmin.get_form, by adding the request as an attribute of the newly created form class .
class EntryAdmin(admin.ModelAdmin):
form = EntryAdminForm
def get_form(self, request, *args, **kwargs):
form = super(EntryAdmin, self).get_form(request, *args, **kwargs)
form.request = request
return form
This works for me:
from django.contrib import admin
from page.models import Page
class PageAdmin(admin.ModelAdmin):
def get_form(self, request, *args, **kwargs):
form = super(PageAdmin, self).get_form(request, *args, **kwargs)
form.base_fields['author'].initial = request.user
return form
admin.site.register(Page, PageAdmin)
I know i am a bit late for posting this solution, but like me if anyone else come across you may try:
def save_model(self, request, obj, form, change):
if getattr(obj, 'author', None) is None:
obj.author = request.user
obj.save()
I've been trying to make the GenericTabularInline class work in a two-admin two-databases setup by inheriting from it and overriding some methods in the BaseModelAdmin class, as is done in the Django docs (https://docs.djangoproject.com/en/dev/topics/db/multi-db/), but if a child model is edited in the inline form, it always writes to the default database (I want the second admin to deal exclusively with a secondary database, models are the same for both), so I must not be overriding some method(s) or doing something wrong. Here's the class I have so far:
class MultiDBGenericTabularInline(generic.GenericTabularInline):
using = settings.SECONDARY_DATABASE
def save_model(self, request, obj, form, change):
# Tell Django to save objects to the 'other' database.
obj.save(using=self.using)
def delete_model(self, request, obj):
# Tell Django to delete objects from the 'other' database
obj.delete(using=self.using)
def queryset(self, request):
# Tell Django to look for objects on the 'other' database.
return super(MultiDBGenericTabularInline, self).queryset(request).using(self.using)
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
# Tell Django to populate ForeignKey widgets using a query
# on the 'other' database.
return super(MultiDBGenericTabularInline, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs)
def formfield_for_manytomany(self, db_field, request=None, **kwargs):
# Tell Django to populate ManyToMany widgets using a query
# on the 'other' database.
return super(MultiDBGenericTabularInline, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs)
#Override these three methods; otherwise the log manager attempts
#to write to the main db and raises an exception.
def log_addition(self, request, object):
pass
def log_change(self, request, object, message):
pass
def log_deletion(self, request, object, object_repr):
pass
Any help or hints are appreciated.
I realize this is an old question, but I've stumbled across a very similar thing recently. The trick is to override the parent Model Admin's save_formset method. In my case, the solution is to do something like this:
class SomeTabularInline(admin.TabularInline):
# stuff
class MyModelAdmin(admin.ModelAdmin):
using = 'something'
inlines = (SomeTabularInline,)
def save_formset(self, request, form, formset, change):
instances = formset.save(commit=False)
for obj in formset.deleted_objects:
obj.delete(using=self.using)
for instance in instances:
instance.save(using=self.using)
formset.save_m2m()
Note: I'm using a TabularInline instance, and not a GenericTabularInline but they both descend from InlineModelAdmin; so I'm hopeful that this would work in your case.
Source: https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_formset