Pitfall guide: How many pitfalls do you need to avoid when you deploy your Django project to Heroku?

Cors cross domain problem

  • Cross-Origin Resource Sharing (CORS) issues may occur in both the local development phase and the Heroku deployment phase, as follows:

  • Issues in the local development phase CORS:

    • CORSProblems can arise when you run your front-end application (such as a Vue.js or React application) and your backend service (such as a Django or Node.js server) locally on different ports. Browsers enforce a same-origin policy for security reasons, which means that JavaScript from one origin (with the same protocol, domain name, and port) can only access resources on that origin. If you try to get a resource from a different origin, you will get CORSan error.

    • For example, if your front-end application is running on localhost:3000, and your back-end service is running on localhost:8000, then a request sent from the front-end application to the back-end service will be considered a cross-origin request.

  • CORS issue during Heroku deployment stage:

    • After deploying to Heroku or any other production environment, your front-end application and back-end service may be hosted on different domains. For example, your frontend app might be hosted on Netlify or Vercel (e.g. https://your-frontend.netlify.app), while your backend service is hosted on Heroku (e.g. https://your-backend.herokuapp.com). In this case, all requests sent by your front-end application to the back-end service will be considered cross-origin requests.
    • Or when your backend code has been deployed on heroku, but the frontend code is still there local, then there is still CORSa problem with the frontend requesting the backend
    • To fix these issues, you need to configure your backend service to allow cross-origin requests from your frontend application. In Django, you can use django-cors-headerspackages to do this.
  • Below I will introduce solutions to cross-domain problems at different stages

localhost stage

  • The fundamental idea to solve the cross-domain problem is to use it CORS header. Of course, we don’t need to set it when developing locally CORS headers, but simply Corsadd a modifier symbol to each function that may cause problems @csrf_exempt, as follows:
    insert image description here

  • This can be very convenient when debugging

  • In Django, @csrf_exemptis a decorator that can be used on a specific view function to make the function exempt from CSRF protection. When you @csrf_exemptdecorate a view function with , the function is excluded from CSRF protection. That is, requests to this function POSTwill not need to carry CSRF token.

  • Here's @csrf_exemptan example of how to use it:

    from django.views.decorators.csrf import csrf_exempt
    
    @csrf_exempt
    def my_view(request):
    	pass
    
  • Again, although this is useful locally, when you actually deploy the server, you still need to solve the cross-domain problem

Heroku Deployment Stages

  • At this time, it is better to change it safely header. The following is the specific method:
  1. Install django-cors-headersthe library:

    pip install django-cors-headers
    
  2. Add this to settings.pyyour INSTALLED_APPS:

    INSTALLED_APPS = [
        ...
        'corsheaders',
        ...
    ]
    
  3. In settings.pythe MIDDLEWARE, CorsMiddlewareadd to the top :

    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware',
        ...
    ]
    
  4. Then you need to add the following setting to your settings:

    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware',
        ...
    ]
    

Procfile startup file

  • ProcfileA file that Heroku uses to know how to run your application. In this file, you define the various process types of the application and the commands corresponding to these processes.

  • This file has no suffix, do not add any suffix yourself, if you are, macosplease be careful not to let the system.txt add the ending to you by default

  • For example, a typical Django app's Procfilemight look like this:

    web: gunicorn YOUR_PROJECT_NAME.wsgi
    
  • In addition, Procfileit can also contain releasea process type, which is the process that runs every time a new version of the application is deployed. For example, you can use releasethe process to run database migrations, which we'll cover later.

  • In general, Procfileit is an important file that tells Heroku how to run your application, including which processes to start and how to start them.

Database database related content

localhost stage

django.db.utils.OperationalError: no such table: nnsh_backend_new_roommember
  • nnsh_backend_new_roommember. This problem may be caused by the following reasons:

    • Models without migrations: When you create a new model or mutate an existing model in Django, you need to create a migration file (pass) python manage.py makemigrationsand then apply the migration (pass python manage.py migrate). If you don't apply migrations, the database tables will not be created.

    • Database out of sync: This problem can occur if your database is out of sync with your code. For example, if you created and migrated the database in the development environment, but did not do the same in the production environment.

    • Wrong database settings: In Django's settings.py file, you need to set the correct values ​​for DATABASES, including database engine, database name, user, password, etc.

  • So I try:

    python manage.py makemigrations
    python manage.py migrate
    
  • But it didn't work, after some exploration, use the following command:

    	python manage.py makemigrations YOUR_PROJECT_NAME
    	python manage.py migrate
    

    insert image description here

  • So the modified command is:

    	python manage.py makemigrations nnsh_backend_new
    	python manage.py migrate
    

Heroku Deployment Stages

During the deployment phase, the database faces several important issues

Correct way of setting in settings.py

  • When deploying Heroku, the official website provides a settings.pytemplate for our reference
  • settings.pyThe part of this Datasetis defined as follows:
    insert image description here

Official settings.py

  • Shown above is my modified code, but settings.pythe example given is as follows:
    insert image description here

  • It can be seen that the official settings.pyAbout Databasesection does not give a complete description, which caused a problem, that is, when I first deployed the code to Heroku, I always reported an error about the database, and the effective error message is:

    django.core.exceptions.ImproperlyConfigured: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.
    
  • This indicates that Django was unable to find a valid database engine configuration when attempting to perform a database operation. But I have set up my Database according to the official setting, so I wonder if the heroku database is very different from the local deployment, and it needs to be set and configured manually in advance.

  • It has been confirmed that it does. When you deploy a Django application that includes a database to Heroku, you need to set up the database on Heroku. If you want to use Heroku's services, you can add Heroku add-ons Postgresin Heroku . This automatically creates a new database and stores the connection information in environment variables.app settingsPostgresPostgreSQLDATABASE_URL

  • The way to manually set up this database is:Overview->Config Add-ons
    insert image description here

  • Search heroku postgresand add
    insert image description here

  • Once you've added the database, Heroku will automatically set an environment variable DATABASE_URLthat contains Heroku Postgresall the information needed to connect to your new database.

  • Then settings.pyadd that line in my way in
    insert image description here

  • What the above code does is read the database URL in the environment variable (which Heroku automatically sets) and use it to configure Django's DATABASESsettings.

makemigration & migrate data migration

  • It’s not over here, because we set up our database on Heroku and settingsconfigured it in , and then we also need to migrate the data, which is migrationthe operation

  • We need to complete this part before the start of the entire application, and the startup of the application is based on our Procfilefile web: gunicorn YOUR_PROJECT_NAME.wsgi, so we need to complete it before this sentencemigration

  • So we will Procfileadd a sentence:

    release: python manage.py makemigrations YOUR_PROJECT_NAME && python manage.py migrate
    web: gunicorn YOUR_PROJECT_NAME.wsgi
    
  • Be sure to pay attention YOUR_PROJECT_NAMEto the part of must use the name of your own project, don't make a mistake~

requirements.txt & runtime.txt versions and libraries

  • requirements.txtThe version information of all packages needed for heroku deployment is pre-written in the file
  • runtime.txtThe file is the specified pythonversion, because heroku itself does not support pythonmany versions, you must find out pythonthe version that heroku can support before you start. For details, please refer to my other article about heroku
  • Be sure to check requirements.txtthat you must check multiple times to ensure that all important packages are written in. If you miss it, it will be debugvery laborious, especially a few particularly important ones:
    Diango==4.0.1
    gunicorn==20.1.0
    diango-heroku==0.3.1
    

Summarize

  1. Cross-domain problems, use cors headerto solve, to modify the corresponding settings.pypart
  2. ProcfileNote that there is no suffix, it is the program startup file for deployment, and it can also be responsible for the migration operation of the heroku database
  3. requirments.txtBe sure to write in full and runtime.txtspecify pythonthe version
  4. settings.pyOverviewFollow the instructions on the official website, but pay attention to the definition of the database part; at the same time, remember to manually set the database in heroku first Postgres, or the database call will fail

Guess you like

Origin blog.csdn.net/qq_42902997/article/details/131522220