2021年3月26日星期五

Django: "AppRegistryNotReady: Apps aren't loaded yet" when deploying to Heroku

I'm consistently running into an error when deploying to production(Heroku), but the app works fine on my localhost. I see that many other people have this issue but none of the solutions work for me. One important note is that I do not call django.setup(), because when I do I get another error (auth.User model not found), but according to the Django docs you should not have to call that when running the app on a web server (as I am). I've been really stuck on this so would appreciate any help anyone can give.

The error is:

File "/app/.heroku/python/lib/python3.6/site-packages/django/apps/registry.py", line 136, in check_apps_ready  2021-03-26T10:33:44.756357+00:00 app[web.1]: raise AppRegistryNotReady("Apps aren't loaded yet.")  2021-03-26T10:33:44.756413+00:00 app[web.1]: django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.  

I'm on Django 3.1.7, and looked at my requirements.txt and i believe my apps are up to date.

File structure: image link

Below is my code:

Procfile

release: python manage.py migrate  web: daphne django_project.asgi:application --port $PORT --bind 0.0.0.0 -v2  worker: python manage.py runworker channels --settings=django_project.settings -v2  

blog/models.py

print('~~~\n\nvery top in blog/models.py\n\n~~~')    from django.db import models  from django.utils import timezone    from django.contrib.auth.models import User    from django.urls import reverse  from datetime import datetime, timedelta      # we're inheriting from the models.Model  class Post(models.Model):      title = models.CharField(max_length=100) # character field      content = models.TextField() # Unrestricted text      date_posted = models.DateTimeField(default=timezone.now)      last_modified = models.DateTimeField(auto_now=True)        # author is a one-to-many relationship which uses a foreign key      # the argument to ForeignKey is the related table      # on_delete tells django to delete all posts by a user when that user is deleted      author = models.ForeignKey(User, on_delete=models.CASCADE)        # Convenience method to print out the title of a Post      def __str__(self):          return self.title        def get_absolute_url(self):          return reverse('post-detail', kwargs={'pk': self.pk})      class Game(models.Model):      name = models.TextField()  # Unrestricted text      platform = models.CharField(max_length=100)  # character field      created_date = models.DateTimeField(default=timezone.now)      name_and_platform = models.TextField(default='N/A') #todo: find a good max char limit        # ForeignKey represents a many to one relationship.      # if user is deleted, all Game records they made are deleted      author = models.ForeignKey(User, on_delete=models.CASCADE)        def __str__(self):          return self.name  # return game name when game.objects.all() is called        def get_name_and_platform(self):          return ''.join([self.name, '(', self.platform, ')'])        def save(self, *args, **kwargs):          self.name_and_platform = self.get_name_and_platform()          super(Game, self).save(*args, **kwargs)          class Trade(models.Model):      name = models.TextField() # Unrestricted text      created_date = models.DateTimeField(default=timezone.now)      is_trade_proposed = models.BooleanField(default=False) # lock the Trade so other users can't match with it        # The user who originally submitted the trade. They can delete the trade record. If their user is deleted, so is the trade      user_who_posted = models.ForeignKey(User, on_delete=models.CASCADE)        # The owned game of the user who created the Trade record. If a game is deleted, so is the trade      # Specify the related_name to avoid the same lookup name (Trade.Game)      owned_game = models.ForeignKey(Game, on_delete=models.CASCADE, related_name='owned_game', db_column='owned_game')        # The desired game of the user who created the Trade record      # Specify the related_name to avoid the same lookup name (Trade.Game)      desired_game = models.ForeignKey(Game, on_delete=models.CASCADE, related_name='desired_game', db_column='desired_game')        def get_trade_name(self):          return ''.join([self.user_who_posted.username, '(', timezone.now().strftime("%b %d, %Y %H:%M:%S UTC"), ')'])        def save(self, *args, **kwargs):          self.name = self.get_trade_name()          super(Trade, self).save(*args, **kwargs)        def __str__(self):          return self.name # return game name when game.objects.all() is called      class Transaction(models.Model):      name = models.TextField() # Unrestricted text      created_date = models.DateTimeField(default=timezone.now)        # The trade of the user who created the Trade record. If a game is deleted, so is the trade      # Specify the related_name to avoid the same lookup name (Trade.Game)      trade_one = models.ForeignKey(Trade, on_delete=models.CASCADE, related_name='trade_one', db_column='trade_one')        # The desired game of the user who created the Trade record      # Specify the related_name to avoid the same lookup name (Trade.Game)      trade_two = models.ForeignKey(Trade, on_delete=models.CASCADE, related_name='trade_two', db_column='trade_two')        # Options: Cancelled: cancelled by user, Cancelled: auto-cancelled due to inactivity for 2 days, Open      status = models.TextField()  # Unrestricted text. Validated in form.        # While the trade is in "Waiting on user..." status, if trade_two.user does not confirm the trade within 3 days, it will be auto-cancelled      expiry_date = models.DateTimeField(default=datetime.today() + timedelta(days=3))        # While the trade is in "Open" status, if the trade does not complete within 9 days after the transaction was created, it will be auto-cancelled      open_expiry_date = models.DateTimeField(default=datetime.today() + timedelta(days=9))        user_cancelled_date = models.DateTimeField(null=True, blank=True)        def get_transaction_name(self):          return ''.join([str(self.trade_one_id), ' and ', str(self.trade_two_id), ' on ', timezone.now().strftime("%b %d, %Y %H:%M:%S UTC"), ''])        def get_status_on_insert(self):          return 'Waiting for 2nd confirmation from ' + str(self.trade_two.user_who_posted)        def save(self, *args, **kwargs):          if self.name == '':              self.name  = self.get_transaction_name()          if self.status == '':              self.status = self.get_status_on_insert()          super(Transaction, self).save(*args, **kwargs)        def __str__(self):          return self.name # return name when game.objects.all() is called        def get_absolute_url(self): #todo: remove?          return reverse('confirmed-trade', kwargs={'pk': self.pk})  

settings.py

# import django # should not need  import os  import django_heroku      print('~~~At top of settings~~~ ')  BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))    SECRET_KEY = 'exhlfdat&vfum(-34*c2uroi(($ww(yo$9pv98=e6p^gl(-eoj' #todo: test removing this in own deployment    ALLOWED_HOSTS = ['*', 'localhost', '127.0.0.1']    # Application definition  # Allows Django to look for models (for Databases)  INSTALLED_APPS = [      'crispy_forms',      'channels',      'dal',      'dal_select2',      'storages',      'blog',      'chat',      'users',      'django.contrib.admin',      'django.contrib.auth',      'django.contrib.contenttypes',      'django.contrib.sessions',      'django.contrib.messages',      'django.contrib.staticfiles',  ]    MIDDLEWARE = [      'django.middleware.security.SecurityMiddleware',      'django.contrib.sessions.middleware.SessionMiddleware',      'django.middleware.common.CommonMiddleware',      'django.middleware.csrf.CsrfViewMiddleware',      'django.contrib.auth.middleware.AuthenticationMiddleware',      'django.contrib.messages.middleware.MessageMiddleware',      'django.middleware.clickjacking.XFrameOptionsMiddleware',  ]    ROOT_URLCONF = 'django_project.urls'    TEMPLATES = [      {          'BACKEND': 'django.template.backends.django.DjangoTemplates',          #'DIRS': [os.path.join(BASE_DIR, '')], #          'DIRS': [],          'APP_DIRS': True,          'OPTIONS': {              'context_processors': [                  'django.template.context_processors.debug',                  'django.template.context_processors.request',                  'django.contrib.auth.context_processors.auth',                  'django.contrib.messages.context_processors.messages',              ],          },      },  ]    WSGI_APPLICATION = 'django_project.wsgi.application'  ASGI_APPLICATION = 'django_project.asgi.application' # older version of django: 'django_project.routing.application'      DB_URL = os.environ['DATABASE_URL']  DATABASE_URL = DB_URL    DATABASES = { # Use this to use local test DB      'default': {          'ENGINE': 'django.db.backends.sqlite3',          'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),      }  }    # Password validation  AUTH_PASSWORD_VALIDATORS = [      {          'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',      },      {          'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',      },      {          'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',      },      {          'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',      },  ]    # Internationalization  # https://docs.djangoproject.com/en/2.1/topics/i18n/  LANGUAGE_CODE = 'en-us'  TIME_ZONE = 'America/Los_Angeles'  USE_I18N = True  USE_L10N = True  USE_TZ = True    # Static files (CSS, JavaScript, Images)  STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')  STATIC_URL = '/static/'    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')  MEDIA_URL = '/media/'    CRISPY_TEMPLATE_PACK = 'bootstrap4'    LOGIN_REDIRECT_URL = 'blog-home'  LOGIN_URL = 'login'    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'  EMAIL_HOST = 'smtp.gmail.com'  EMAIL_PORT = 587  EMAIL_USE_TLS = True  EMAIL_HOST_USER = os.environ.get('EMAIL_USER')  EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_PASS')    AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')  AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')  AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')    AWS_S3_FILE_OVERWRITE = False  AWS_DEFAULT_ACL = None    DEBUG = 'True'    CHANNEL_LAYERS = {      'default': {          'BACKEND': 'channels_redis.core.RedisChannelLayer',          'CONFIG': {              "hosts": [os.environ.get('REDIS_URL', 'redis://localhost:6379')],          },      },  }    django_heroku.settings(locals()) # maybe need maybe not    # CACHES = { # maybe need maybe not  #     "default": {  #          "BACKEND": "redis_cache.RedisCache",  #          "LOCATION": os.environ.get('REDIS_TLS_URL'),  #          "OPTIONS": {  #             "CONNECTION_POOL_KWARGS": {  #                 "ssl_cert_reqs": False  #             }  #         }  #     }  # }    DATA_UPLOAD_MAX_NUMBER_FIELDS = 4000      # django.setup() #todo maybe need #MAY NEED TO DO THIS, BUT WHEN I DO I GET "auth.User model not found" error  

asgi.py

import os  import django  from channels.routing import get_default_application    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')  django.setup()  application = get_default_application()  

~~~IMPORTANT UPDATE:~~~

In my Procfile, I switched from using daphne to gunicorn just as a test, and the app built successfully! But now, I am getting this error below. It seems as though Django cannot load my 'django.contrib.auth' app for some reason. This is similar to another error i was having before: ImproperlyConfigured: AUTH_USER_MODEL refers to model 'auth.User' that has not been installed. Details on that error are at this post.

enter image description here

I'm desperate at this point and considering destroying my database and then migrating but i'm not sure if that will cause problems or will even fix the issue. I don't have any valueable data at this point so maybe it's worth a shot?

https://stackoverflow.com/questions/66815416/django-appregistrynotready-apps-arent-loaded-yet-when-deploying-to-heroku March 26, 2021 at 06:47PM

没有评论:

发表评论