0

I am trying to implement a django solo kind of custom model admin where each user has his own solo object to change. So the instance id should change when user logs in admin panel. Change view is working fine but after changing the field & save, it is not saving the changes. Below is my custom ModelAdmin code -

class DatabaseSessionModelAdmin(admin.ModelAdmin):
    form = DatabaseSessionForm

    def get_queryset(self, request):
        return self.model.objects.filter(user=request.user)

    def has_add_permission(self, request):
        return False

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

    def get_urls(self):
        urls = super(DatabaseSessionModelAdmin, self).get_urls()

        if not settings.DB_ADMIN_SKIP_OBJECT_LIST_PAGE:
            return urls
        try:
            model_name = self.model._meta.model_name
        except AttributeError:
            model_name = self.model._meta.module_name.lower()
        self.model._meta.verbose_name_plural = self.model._meta.verbose_name
        url_name_prefix = '%(app_name)s_%(model_name)s' % {
            'app_name': self.model._meta.app_label,
            'model_name': model_name,
        }
        custom_urls = [
            re_path(r'^$',
                    self.admin_site.admin_view(self.change_view),
                    # {'object_id': str(self.singleton_instance_id)},
                    name='%s_change' % url_name_prefix),
        ]
        return custom_urls + urls

    def response_change(self, request, obj):
        msg = _('%(obj)s was changed successfully.') % {
            'obj': force_str(obj)}
        if '_continue' in request.POST:
            self.message_user(request, msg + ' ' +
                              _('You may edit it again below.'))
            return HttpResponseRedirect(request.path)
        else:
            self.message_user(request, msg)
            return HttpResponseRedirect("../../")

    def change_view(self, request, object_id=None, form_url=None, extra_context=None):
        object_id = DatabaseSession.objects.filter(user=request.user).first().id

        if not extra_context:
            extra_context = dict()
        extra_context['skip_object_list_page'] = True

        return super(DatabaseSessionModelAdmin, self).change_view(
            request,
            str(object_id),
            form_url=form_url,
            extra_context=extra_context,
        )

    def history_view(self, request, object_id, extra_context=None):
        object_id = DatabaseSession.objects.filter(user=request.user).first().id

        if not extra_context:
            extra_context = dict()
        extra_context['skip_object_list_page'] = settings.DB_ADMIN_SKIP_OBJECT_LIST_PAGE

        return super(DatabaseSessionModelAdmin, self).history_view(
            request,
            str(object_id),
            extra_context=extra_context,
        )

So, I tried to solve this in many ways, but nothing's working. In my thoughts, if I can get the current user or request in get_urls method, that might lead to a solution. I tried crum libray, django-current-user, even implemented my own middleware, but all failed. Please help me resolve this or suggest me any workarounds please. Thanks in advance.

  • well if you think your problem will be solved just by getting the current user in `get_url` method, I guess you can access it by `self.request.user`. If you want to have more control on saving an object check the `save_model`. You can also takea look at `clean` method. – A D Sep 09 '22 at 08:34
  • there is no attribute 'request' for model admin, it gives attribute error. And I don't want any control over model, because DatabaseSession model has only 2 fields, user (which is set to current user by default) & database (which is foreign key to Database model), when I change database field, it goes back to the default value, even after saving. – Mahmud Abdur Rahman Sep 09 '22 at 08:54
  • Also the response_change method doesn't seem to be working, I've called print method there, but those print methods are not working. – Mahmud Abdur Rahman Sep 09 '22 at 08:59
  • first of all you are right, `self.request.user` will throw an error, sorry for that. `response_change` does not work because actually you do not perform any save action, take a look at [doc](https://docs.djangoproject.com/en/4.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.response_change). What I see from your modification of `change_view ` is that you are getting just the id and pay attention, `return super(DatabaseSessionModelAdmin, self)....` with `object_id` does not perform save! – A D Sep 09 '22 at 09:25
  • _So the instance id should change when user logs in admin panel_. How do you perform a change without saving it ?! _**Change view is working fine** but after changing the field & save, **it is not saving the changes**._ ... So, it is not working fine if it is not saving! anyway, you can also take a look at `render_change_form` to access the object for two cases, change and add. – A D Sep 09 '22 at 09:29
  • I've added the record for a user via middleware, so any superuser logs in, it checks for his record or create one for him if not exists with a default value and saves it in the request object. That's why I tried to access the request object in get_urls method, since this model admin is only for the change purpose, only database value change from the default value. Whenever user logs in, it set to the default value, so if he wants to change it, I'm trying to provide this custom model admin. – Mahmud Abdur Rahman Sep 09 '22 at 09:47
  • From my knowledge, if I don't override the save method, it should get called with the default one, right? I'm not overriding any other methods, since I only need to change one field, which is database foreign key field. This should be saved automatically, no?! – Mahmud Abdur Rahman Sep 09 '22 at 09:53

0 Answers0