Hi @KenWhitesell:
Thanks again for helping come up with this Python subquery scripting gymnastic so far because there is no way I could have figured this out on my own.
Here is the latest code snippet I am working with based on your suggestion:
class ScriptSuggestionDetailView(LoginRequiredMixin,DetailView):
model = ScriptSuggestion
script_type = ContentType.objects.get_for_model(ScriptSuggestion)
ScriptSuggestion.objects.annotate(
last_change=Subquery(
LogEntry.objects.filter(
content_type=script_type,
action_flag=CHANGE,
object_id=Cast(
OuterRef('id'),
CharField()
)
).order_by('-action_time').values('action_time')[:1]
)
).order_by('-last_change')
context_object_name = 'scriptsuggestions'
To resolve the issues referred to by my editor’s Python linter, I found all the modules in the Django docs and added the proper import references at the top of my views.py:
from django.contrib.admin.models import CHANGE, LogEntry
from django.db.models import OuterRef, Subquery
from django.contrib.contenttypes.models import ContentType
from django.db.models.functions import Cast
from django.db.models import CharField
That’s everything. All the linting errors are gone. When I run the server, there is no traceback and I can access the Admin Dashboard and view the full site. That’s progress.
The problem now is, when the Admin changes existing content, the way the list of objects are ordered remains unchanged when Django serves the ListView template. It’s like the the new code is having no impact. It’s the same as before. I also tried creating brand new test content and the new list item continues to appear at the bottom of the list like it always has instead of appearing at the top. For the .order_by()
string paramaters, I tried combinations of changing with and without “-
” that is part of the string but there is no change in the sorting behaviour.
For what it is worth, here is my for loop and how my unordered list is constructed in my template:
<ul>
<h4> CUSTOMIZED <br> SCRIPTS </h4>
<div class="box">
{% for script in scriptsuggestions %}
<li class="flex-item"><a href="/scripting/{{script.slug}}">{{script.title}}</a></li>
{% endfor %}
</div> <!-- end box -->
</ul>
Earlier in this thread, Ken said:
I’m not sure I completely understand this quote but could the issue I am describing above involve the way the list is sorted based on changes made by the Admin as you explain here?
My Django shell is also pointing to an issue with my models. Django says:
You have 2 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): contents.
Run ‘python manage.py migrate’ to apply them.
When I migrate the db, the traceback points to an id integer field issue, captured below at the bottom of this post. I am not sure if resolving the LogEntry sorting issue with subquery ‘gymnastic’ we have been working on so far is related to this, but I thought I would mention it.
As you can see below, Python is saying that the entry in the database needs to a number (integer) but it’s a datetime value. I think I made this mistake previously when I made a migration a few weeks ago and Django prompted me for a default entry. I realize my mistake now. I tried appending id = models.IntegerField(blank=False, null=False)
to my ScriptSuggestion class in models.py and generating some new migrations but Django didn’t like that either so I commented it back out.
In my next attempt to fix this, I moved the 2 most recent auto-generated migrations into a backup directory. I then tried to re-generate new migrations but Django says “No changes detected”. When I run the server, Django says:
System check identified no issues (0 silenced).
The Django server proceeds to run without showing any other issues and my site seems to otherwise be working. Was this the right next step - - to backup the offending migrations?
The original issue remains: Class objects are still not being sorted according to log entries in Descending order when the ListView template is being served.
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contents, contenttypes, sessions
Running migrations:
Applying contents.0009_alter_scriptsuggestion_managers_and_more...Traceback (most recent call last):
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/models/fields/__init__.py", line 2018, in get_prep_value
return int(value)
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'datetime.datetime'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/manage.py", line 22, in <module>
main()
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
utility.execute()
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 440, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/core/management/base.py", line 402, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/core/management/base.py", line 448, in execute
output = self.handle(*args, **options)
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/core/management/base.py", line 96, in wrapped
res = handle_func(*args, **kwargs)
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/core/management/commands/migrate.py", line 349, in handle
post_migrate_state = executor.migrate(
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/migrations/executor.py", line 135, in migrate
state = self._migrate_all_forwards(
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/migrations/executor.py", line 167, in _migrate_all_forwards
state = self.apply_migration(
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/migrations/executor.py", line 252, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/migrations/migration.py", line 130, in apply
operation.database_forwards(
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/migrations/operations/fields.py", line 108, in database_forwards
schema_editor.add_field(
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/backends/base/schema.py", line 636, in add_field
definition, params = self.column_sql(model, field, include_default=True)
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/backends/base/schema.py", line 353, in column_sql
" ".join(
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/backends/base/schema.py", line 304, in _iter_column_sql
default_value = self.effective_default(field)
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/backends/base/schema.py", line 423, in effective_default
return field.get_db_prep_save(self._effective_default(field), self.connection)
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/models/fields/related.py", line 1146, in get_db_prep_save
return self.target_field.get_db_prep_save(value, connection=connection)
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/models/fields/__init__.py", line 925, in get_db_prep_save
return self.get_db_prep_value(value, connection=connection, prepared=False)
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/models/fields/__init__.py", line 2703, in get_db_prep_value
value = self.get_prep_value(value)
File "/home/<user>/dev/projects/python/2018-and-2020/hypno_juicer/venv/lib/python3.10/site-packages/django/db/models/fields/__init__.py", line 2020, in get_prep_value
raise e.__class__(
TypeError: Field 'id' expected a number but got datetime.datetime(2022, 12, 4, 9, 51, 33, 379630, tzinfo=datetime.timezone.utc).