Issues and Improvements to the The Django Administration

121 views
Skip to first unread message

Muskan Vaswan

unread,
Dec 15, 2020, 1:42:40 PM12/15/20
to Django developers (Contributions to Django itself)
I have the following suggestions and issues with the Django site administration:

1. When deleting or adding items in Bulk (especially deleting), The Recent Actions should show “Deleted 15 Items” rather than every deleted item singularly which just occupies space and doesn't make a lot of sense and put bluntly is a waste of space. (ScreenShot attached). This could also be in the form of a dropdown which on click would show us every single one of the logs. Now I know this may not be a major change to the page but I do think it would improve the quality of the admin page. Do tell me if you agree or disagree 
After looking at the code for this, I realized that this wouldn’t be as easy it seems because (at least as far as I could understand) the context picks the action history from the LogEntry Model and passes it into the context. But a possible solution to this would be changing the query to give changes made on the same timestamp and tag as a list of actions and the final context could be the list of all such distinct timestamps.


2. The way the default index template can be overwritten by the user by specifying admin.index_template, I think it might be possible to give such an option for singular components of the admin site. For example, the entire header (Line 30 to 62) could be put inside a block and then use an 
{% include header.html %} which would contain the code for the entire header. And we could make this file default and give the option to overwrite this particular template. We ensure that the components hold their designated positions and leave the rest up to the user. We could also do this for other elements and components like the footer. I think this would increase ease of customization. Please give your views regarding the same.

3. Last and the least, The method for unregistering models form the admin site is not in the documentation. I only found it existed while going through the source code and on StackOverflow. Is there a reason for this or is this a lack of documentation that needs to be fixed? 

Regards
Muskan Vaswan

Muskan Vaswan

unread,
Dec 15, 2020, 1:44:26 PM12/15/20
to Django developers (Contributions to Django itself)
WhatsApp Image 2020-12-15 at 10.55.37 PM.jpeg

Adam Johnson

unread,
Dec 15, 2020, 2:43:39 PM12/15/20
to django-d...@googlegroups.com
1. When deleting or adding items in Bulk (especially deleting), The Recent Actions should show “Deleted 15 Items”

This would be nice, but you've spotted the problem with querying the LogEntry table. If a user deleted e.g. 1,000 items, we wouldn't want to query for 1000 LogEntry objects only to accumulate them into a single row for display. I'm not sure there's a neat solution without changing the data model, and whether that would be worth it for most sites.

2. The way the default index template can be overwritten by the user by specifying admin.index_template, I think it might be possible to give such an option for singular components of the admin site. For example, the entire header (Line 30 to 62) could be put inside a block and then use an

When overriding the base admin template I don't change those attributes, but instead add a template file admin/base_site.html in my project's templates that starts with "{% extends "admin/base_site.html" %}" , like: https://docs.djangoproject.com/en/3.1/howto/overriding-templates/#extending-an-overridden-template  . Does this not support your use case?

If so, I think adding a few more {% block %} declarations would be fine.

3. Last and the least, The method for unregistering models form the admin site is not in the documentation.

Thanks, this looks like an oversight. Several snippets in the docs recommend using unregister(). I made a ticket: https://code.djangoproject.com/ticket/32273#ticket

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/58cf1866-a505-4ced-8ca2-c3aa449f57a3n%40googlegroups.com.


--
Adam

Muskan Vaswan

unread,
Dec 15, 2020, 5:02:56 PM12/15/20
to Django developers (Contributions to Django itself)
1. Agreeably this won’t be easy but I might have a way of doing this without having to make changes to the data model. We can leave the data model as it is but manipulate the context that we give to by changing the simple query (Line 16) to something slightly more complex. 
Like maybe 
    #logs = LogEntry.objects.values('action_time', 'action_flag', 'user', 'content_type').distinct()
            #for l in logs:
            #   e = LogEntry.objects.filter(Q(action_time=l['action_time']) && Q(action_time=l['action_flag']))
            #   if e.count() > 1:
            #        entry = Entry(l, e)
            #        entries.append(entry)
            #   else:
            #       entries.append(e) 
Where Entry() is a class (but not model) having necessary elements of LogEntry which are used in the templates already. Note that this is the most basic draft just to give an idea of what I’m trying to say. 
About having 1000 rows, you're right I guess we will have to reach a consensus to put an upper limit to the number of rows that can be encapsulated into one if we do decide to do this. I would suggest something like 50 or 100. Let me know what you think, and if I made any sense at all. There might be a point that this whole thing becomes an overkill, but as long as we don’t do something too major, I think it’ll be pleasing.

2. Yes that fits my use case quite well. I think adding just a couple more block elements will definitely do it.

3. Thank you! Glad I could contribute in some way.
 
Regards
Muskan Vaswan

Adam Johnson

unread,
Dec 15, 2020, 5:17:12 PM12/15/20
to django-d...@googlegroups.com
 I would suggest something like 50 or 100. Let me know what you think, and if I made any sense at all

But in this case, we might show something like "User X deleted 50 rows", when really they deleted 1000. I don't think we'd want to show such an inaccurate message.

If you want though, you could put together a proof-of-concept. Perhaps others would also prefer your suggestion.

2. Yes that fits my use case quite well. I think adding just a couple more block elements will definitely do it.

Please open a ticket/PR

3. Thank you! Glad I could contribute in some way.

You can pick up the ticket and make the docs patch :)




--
Adam

Muskan Vaswan

unread,
Dec 15, 2020, 6:16:49 PM12/15/20
to django-d...@googlegroups.com
1. Agreeably this won’t be easy but I might have a way of doing this without having to make changes to the data model. We can leave the data model as it is but manipulate the context that we give to by changing the simple query (Line 16) to something slightly more complex. 
Like maybe 
    #logs = LogEntry.objects.values('action_time', 'action_flag', 'user', 'content_type').distinct()
            #for l in logs:
            #   e = LogEntry.objects.filter(Q(action_time=l['action_time']) && Q(action_time=l['action_flag']))
            #   if e.count() > 1:
            #        entry = Entry(l, e)
            #        entries.append(entry)
            #   else:
            #       entries.append(e) 
Where Entry() is a class (but not model) having necessary elements of LogEntry which are used in the templates already. Note that this is the most basic draft just to give an idea of what I’m trying to say. About having 1000 rows, we will have to reach a consensus to put an upper limit to the number of rows that can be encapsulated into one. I would suggest something like 50 or 100. Let me know what you think, and if I made any sense at all. There might be a point that this whole thing becomes an overkill, but as long as we don’t do something too major, I think it’ll be pleasing.

2. Yes that fits my use case quite well. I think adding just a couple more block elements will definitely do it.

3. Thank you! Glad I could contribute in some way.

Carles Pina i Estany

unread,
Dec 15, 2020, 6:56:23 PM12/15/20
to django-d...@googlegroups.com

Hi,

On Dec/16/2020, Muskan Vaswan wrote:

> LogEntry which are used in the templates already. Note that this is the
> most basic draft just to give an idea of what I’m trying to say. About
> having 1000 rows, we will have to reach a consensus to put an upper limit
> to the number of rows that can be encapsulated into one. I would suggest

If this was done it would be nice to see something like:
"Deleted 15 items"
"Deleted 515 items"
"Deleted more than 1000 items" (if it deleted more than 1000 if 1000 is
the upper limit)

So it's informative, correct and should not be a database killer. I
haven't checked recently the datamodel but to avoid the COUNT I think
that it can be done with a query, slicing it to limit+1 (to force a
LIMIT in the SQL) and if there are limit+1 elements then say "Deleted
more than..." or probably some other way that I haven't thought now :-)

Cheers,

--
Carles Pina i Estany
https://carles.pina.cat

Akshat Sharma

unread,
Dec 15, 2020, 9:17:30 PM12/15/20
to django-d...@googlegroups.com
Hi

Well I am an webdevloper and pretty new to the django so

but If the issue is only to make log more efficient and useful then we can implement javascript into the admin site

it can be resolved with pretty simple js and can be directly implemented into HTML and can be a major advantage in scaling up

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.

Muskan Vaswan

unread,
Dec 16, 2020, 12:20:22 AM12/16/20
to django-d...@googlegroups.com
The point is that there is a way, in fact multiple ways that this could be implemented without changing the models. A change to the method I suggested in my last mail would be to avoid looping over the query set at all or even the Entry() class and using values and the the Count() annotation in a single query and instead of showing the repr of the object deleted we could say something like “Deleted 1item” or “Deleted 10 items” which on click could show us the group of items being talked about. 

Akshat: I’m not sure how you plan on grouping the query set appropriately using javascript. I don’t think that is implementable. And even if it is, I don’t see how it would be more efficient.

Carles Pina I Estany: While I understand what you’re trying to do I don’t know why we are trying to avoid COUNT is there a best practice associated with this that I don’t know about?
However I do see a concern in adding a loop to the queryset right there in python. A slightly better solution would be simply saying 
Entries = LogEntry.objects.values(‘action_time’,’action_flag’,’user’).annotate(no_of_items = Count(‘id’)) and switching up things like 
{{ entry.object_repr }} in index.html to accommodate the dictionary that will be returned so that recent actions doesn’t deal directly with action objects at all.

Another proposal which would solve the problem of potentially encapsulating too much would be to add a view for a logs.html that shows very single query with pagination for the query set. This way the users who really want to see all the details of all of the logs, have a way to do it  (without having to make query to logEntry on their end) and the recent actions will have a lot cleaner look. 

I’m sure there are little details that can always be improved in every solution. I would really appreciate your inputs on the same

Adam: Let me know if this seems like a remotely satisfactory solutions or if there are other problems I should consider.

If this seems like a helpful proposal I would like to take this entire segment up for my GSoC Proposal in 2021.

Regards
Muskan Vaswan

Carles Pina i Estany

unread,
Dec 16, 2020, 3:47:34 AM12/16/20
to django-d...@googlegroups.com

Hi,

On Dec/16/2020, Muskan Vaswan wrote:

> Carles Pina I Estany: While I understand what you’re trying to do I
> don’t know why we are trying to avoid COUNT is there a best practice
> associated with this that I don’t know about?

We are (or... I was :-) ) trying to answer this question as close as
to the database:
-"Are more than X number of rows?"

With COUNT we would answer:
-"How many rows are there?"

Depends on the model, indexes, data in the DB and database the COUNT
operation can take longer than the other way to know if there are more
than X rows. It needs proper checking.

It's more or less what's explained here:
https://docs.datasette.io/en/stable/sql_queries.html#pagination
but I was thinking in terms of a Django ORM

Sorry if this was a detour on the higher level discussion. My message is
that it probably can be done without COUNT if need to be and show "more
than X rows" instead of the exact number of rows.

Muskan Vaswan

unread,
Dec 16, 2020, 10:25:34 AM12/16/20
to django-d...@googlegroups.com


On Dec 16, 2020, at 2:17 PM, Carles Pina i Estany <car...@pina.cat> wrote:

My message is
that it probably can be done without COUNT if need to be and show "more
than X rows" instead of the exact number of rows.

Well yes this makes sense to me now,
but only in the sense that we would first check whether some query exceeded the limit or not and only count the exact amount of objects if it's under the limit. 
But even so if you consider the actual implementation, you'd have to make two queries: one for all the distinct groups of timestamps and action tags and run a loop on them and so on... This is difficult to explain in words but basically it would add a lot more queries this way... at least the way I visualize it happening here. 

But also this is something I didn't know about so this was quite educational, thank you.

Regards 
Muskan Vaswan
Reply all
Reply to author
Forward
0 new messages