I have some code being written where I have tried to automate adding and deleting model objects as I have shown below in my models.py:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save, post_delete
from django.dispatch import Signal
from django.db.models import Max, Count
from django.apps import apps
# Create your models here.
class Player(models.Model):
player_name = models.CharField(max_length=150)
current_level_no = models.IntegerField(null=True)
no_of_moves = models.IntegerField(null=True)
class Meta:
verbose_name_plural = 'Players'
def __str__(self):
return self.player_name
class PlayerStats(models.Model):
player_name = models.ForeignKey(to=Player, on_delete=models.CASCADE)
level_no = models.IntegerField(null=True)
moves = models.IntegerField(null=True)
class Meta:
verbose_name_plural = 'Players Stats'
# It works!
TotalLevels = 15
MaxCurrentLevel = PlayerStats.objects.aggregate(max_levels=Max('level_no'))['max_levels']
PlayerCount = Player.objects.aggregate(count_players=Count('player_name', distinct=True))['count_players']
def create_player(sender, instance, created, **kwargs):
if created:
new_username=instance.username
Player.objects.create(player_name=new_username, current_level_no=None, no_of_moves=None)
def delete_player(sender, instance, **kwargs):
deleted_username=instance.username
Player.objects.filter(player_name=deleted_username).delete()
def create_player_stat(sender, instance, **kwargs):
for x in range(1, TotalLevels+1):
PlayerStats.objects.create(player_name=instance, level_no=x, moves=None)
if MaxCurrentLevel != TotalLevels and PlayerCount != 0:
if MaxCurrentLevel < TotalLevels:
for x in Player.objects.all().values_list('player_name', flat=True):
instance = Player.objects.get(player_name=x)
for y in range(TotalLevels-MaxCurrentLevel, TotalLevels+1):
PlayerStats.objects.create(player_name=instance, level_no=y, moves=None)
else:
for y in range(MaxCurrentLevel-TotalLevels, MaxCurrentLevel+1):
b = PlayerStats.objects.filter(level_no=y, moves=None)
print(b)
b.delete()
post_save.connect(create_player, sender=User)
post_delete.connect(delete_player, sender=User)
post_save.connect(create_player_stat, sender=Player)
What I have done is make sure that there are only as many Foreign Key model objects of PlayerStats associated with each Player(kinda like Primary key in this case) of the Player Model and that number is governed by the Total levels number. So if there are more or less levels associated with each player in PlayerStats Model than the Total levels value, I made a conditional piece of code with a couple of loops to accordingly delete or add the Model objects.
The problem really is that the creation part works fine when I need more levels and increase Total Levels. But when I decrease it, that is delete the extra, I get an error: “Models aren’t loaded yet”.
Here is the full error if you need it:
C:\Users\Prithvi\Desktop\Prithvi\PROJECTS\Rahul stuff\bloxnsims\website>python manage.py runserver
<QuerySet [<PlayerStats: PlayerStats object (70)>, <PlayerStats: PlayerStats object (86)>, <PlayerStats: PlayerStats object (104)>]>
<QuerySet [<PlayerStats: PlayerStats object (70)>, <PlayerStats: PlayerStats object (86)>, <PlayerStats: PlayerStats object (104)>]>
Watching for file changes with StatReloader
Exception in thread django-main-thread:
Traceback (most recent call last):
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\utils\autoreload.py", line 54, in wrapper
fn(*args, **kwargs)
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\commands\runserver.py", line 109, in inner_run
autoreload.raise_last_exception()
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\utils\autoreload.py", line 77, in raise_last_exception
raise _exception[1]
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\__init__.py", line 337, in execute
autoreload.check_errors(django.setup)()
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\utils\autoreload.py", line 54, in wrapper
fn(*args, **kwargs)
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\__init__.py", line 24, in setup
apps.populate(settings.INSTALLED_APPS)
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\apps\registry.py", line 114, in populate
app_config.import_models()
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\apps\config.py", line 211, in import_models
self.models_module = import_module(models_module_name)
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "C:\Users\Prithvi\Desktop\Prithvi\PROJECTS\Rahul stuff\bloxnsims\website\bloxors\models.py", line 79, in <module>
b.delete()
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\query.py", line 710, in delete
collector.collect(del_query)
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\deletion.py", line 188, in collect
if self.can_fast_delete(objs):
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\deletion.py", line 150, in can_fast_delete
for related in get_candidate_relations_to_delete(opts)
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\deletion.py", line 58, in get_candidate_relations_to_delete
f for f in opts.get_fields(include_hidden=True)
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\options.py", line 734, in get_fields
return self._get_fields(include_parents=include_parents, include_hidden=include_hidden)
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\options.py", line 794, in _get_fields
all_fields = self._relation_tree
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\utils\functional.py", line 80, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\options.py", line 707, in _relation_tree
return self._populate_directed_relation_graph()
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\options.py", line 678, in _populate_directed_relation_graph
all_models = self.apps.get_models(include_auto_created=True)
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\apps\registry.py", line 178, in get_models
self.check_models_ready()
File "C:\Users\Prithvi\AppData\Local\Programs\Python\Python36\lib\site-packages\django\apps\registry.py", line 140, in check_models_ready
raise AppRegistryNotReady("Models aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
What utterly made me go mad about this is that this error is so vague and I have had it come up a bunch of times. I have had to scratch ideas I have had in mind and start fresh to get done what I want, always with fear about if my new method or approach will also become an error! All I get to know is that I need to do something else and that my current method/approach is a dead-end! I am sorry if this is a little ranty, but I have been pulling my hair out about this so much to the point that if I keep this up, I might actually go bald in a year!
I am clearly not as well-versed with django as much as you all are and as a fellow django user, I request your help on this issue. I am greatful for whatever help I get!