在 AZURE 上部署 Django REST API 后端

问题描述 投票:0回答:1

我尝试解决如何在 Azure 上部署 Django 项目,遵循了许多教程,但在这一点上我无法指出问题所在。

从 GitHub 部署,部署多次成功,但我无法访问我的应用程序,通过浏览器运行时,我大多收到 404 或应用程序错误。 我已经在本地迁移了 postgre,但我想使用 Azure postgre DB。

一直在迎合 ENV 变量,我无法连接到 SHH 来应用迁移,CONN CLOSE ..等 所以我现在不知道从哪里开始?

我尝试过微软指南、互联网指南、向ChatGPT寻求帮助。 我想在 Azure 上部署我的 Django 应用程序,但现在不知道“如何做”。

编辑:添加了代码,抱歉延迟了。

设置.PY

#default moduuli
from pathlib import Path

#ympäristö muuttuja moduulit
import os
from dotenv import load_dotenv

#lataa ympäristö muuttujat
load_dotenv()

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv('SECRET_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.getenv('DEBUG') == 'True'  # Muunna merkkijonoksi booleaniksi


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'main',
    'rest_framework',
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    '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 = 'restapi.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        '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 = 'restapi.wsgi.application'


# Databases
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases


'''
#sqlite
#uncomment to use

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
'''


#Postgre
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('DBNAME'),
        'HOST': os.environ.get('DBHOST'),
        'USER': os.environ.get('DBUSER'),
        'PASSWORD': os.environ.get('DBPASS'),
    }
}



# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators

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/4.2/topics/i18n/

LANGUAGE_CODE = 'fi-fi'
#TIME_ZONE = 'UTC'
TIME_ZONE = 'Europe/Helsinki'
USE_TZ = True
USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/

STATIC_URL = 'static/'

# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

#HUOM
#Muut asetukset tänne!

######################

#Tietoliikenne asetukset
ALLOWED_HOSTS = [
    '192.168.201.225',  #oma IP
    'localhost',
    '127.0.0.1',
]


CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
    "http://127.0.0.1:5000",
    "http://192.168.201.225:8000",  # Lisää oma IP
    "http://192.168.201.225",      # Lisää oma IP

]       
#Django 4 ---> tarvitaan cross site request forgery määritys
CSRF_TRUSTED_ORIGINS = [
    "http://localhost:3000",
    "http://127.0.0.1:5000", 
    "http://192.168.201.225",# Lisää oma IP

]
#vain testausta varten ei tuotantoon!
#CSRF_COOKIE_SECURE = False

#istunnon cookie timeout
#SESSION_COOKIE_AGE = 3600

模型.PY:

# main/models.py

from django.db import models
from django.contrib.auth.models import User

class Post(models.Model):
    content = models.TextField()  # Postin sisältö
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)


    def __str__(self):
        return f"{self.author.username} - {self.content[:20]}..."

class Comment(models.Model):
    comment_content = models.TextField()  # Kommentin sisältö
    commenter = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments')
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"{self.commenter.username} - {self.comment_content[:20]}..."

class Like(models.Model):
    liker = models.ForeignKey(User, on_delete=models.CASCADE, related_name='likes')
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='likes')

    def __str__(self):
        return f"{self.liker.username} liked {self.post.content[:20]}..."

API_VIEWS.PY:

# main/api_views.py
#REST Api näkymä funktiot
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework import viewsets, permissions, status, generics
from rest_framework.response import Response
from .models import Post, Comment, Like, User
from .serializers import PostSerializer, CommentSerializer, LikeSerializer, SignupSerializer
from django.contrib.auth import authenticate, login, logout
from .serializers import UserSerializer
from django.http import JsonResponse
from django.middleware.csrf import get_token
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from rest_framework import viewsets, permissions
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import AllowAny

'''
#Poistaa CSRF tarkistuksen testausta varten
#Viittaa ViewSetissä lisäämäällä --> authentication_classes = [CsrfExemptSessionAuthentication]
class CsrfExemptSessionAuthentication(SessionAuthentication):
    def enforce_csrf(self, request):
        return  # Ei tarkista CSRF-tokenia
'''

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all().order_by('-created')
    serializer_class = PostSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    #Poistaa CSRF tarkistuksen
    #authentication_classes = [CsrfExemptSessionAuthentication]
    
    def perform_create(self, serializer):
        serializer.save(author=self.request.user)

class CommentViewSet(viewsets.ModelViewSet):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]

    def perform_create(self, serializer):
        print("Received data:", self.request.data)  # Tulostaa saatu data
        post_id = self.request.data.get('post')
        print("Post ID:", post_id)  # Tulostaa post_id:n
        try:
            post = Post.objects.get(id=post_id)
            print("Post found:", post)  # Tulostaa löytyneen postin
            serializer.save(commenter=self.request.user, post=post)
        except Post.DoesNotExist:
            print(f"Post with id {post_id} does not exist.")
        except Exception as e:
            print(f"An error occurred: {str(e)}")

class LikeViewSet(viewsets.ModelViewSet):
    queryset = Like.objects.all()
    serializer_class = LikeSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    def get_queryset(self):
        # Palauttaa vain kirjautuneen käyttäjän querysetin
        return User.objects.filter(id=self.request.user.id)

#Käyttäjä tiedot
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def user_profile_view(request):
    """
    Palauttaa kirjautuneen käyttäjän profiilitiedot.
    """
    user = request.user
    serializer = UserSerializer(user)
    return Response(serializer.data)    


@api_view(['POST'])
def login_view(request):
    """
    Ohje.
    Käyttäjän kirjautuminen.
    Kirjoita käyttäjätunnus ja salasana POST-pyyntöön JSON-muodossa ja merkkijonot string tyyppinä. 
    Esim:

    {
    "username": "Käyttäjä",
    "password": "salasana"
    }
    
    """
    username = request.data.get('username')
    password = request.data.get('password')
    user = authenticate(request, username=username, password=password)

    if user is not None:
        login(request, user)
        return Response({'message': 'Login successful'}, status=status.HTTP_200_OK)
    else:
        return Response({'error': 'Invalid credentials'}, status=status.HTTP_400_BAD_REQUEST)


# Tunnusten luonti API endpoint
@api_view(['POST'])
def signup(request):
    serializer = SignupSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response({"message": "User created successfully!"}, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['POST'])
def logout_view(request):
    logout(request)
    return Response({'message': 'Logged out successfully'}, status=status.HTTP_200_OK)

#tee csfr token haku kun suoritetaan POST ja DELETE pyyntöjä
def csrf_token_view(request):
    csrf_token = get_token(request)
    return JsonResponse({'csrfToken': csrf_token})

序列化器.PY

# main/serializers.py
from rest_framework import serializers
from .models import Post, Comment, Like
from django.contrib.auth.models import User


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'first_name', 'last_name']


class PostSerializer(serializers.ModelSerializer):
    author = UserSerializer(read_only=True)

    class Meta:
        model = Post
        fields = ['id', 'author', 'content', 'created']
        

class CommentSerializer(serializers.ModelSerializer):
    commenter = UserSerializer(read_only=True)
    post = PostSerializer(read_only=True)

    class Meta:
        model = Comment
        fields = ['id', 'commenter', 'post', 'comment_content', 'created']  # päivitetty kentät 'user' -> 'commenter', 'content' -> 'comment_content', ja 'created_at' -> 'created'
        read_only_fields = ['commenter', 'created']  # commenter kenttä vain luettavaksi
        
class LikeSerializer(serializers.ModelSerializer):
    liker = UserSerializer(read_only=True)
    post = PostSerializer(read_only=True)

    class Meta:
        model = Like
        fields = ['id', 'liker', 'post']  # päivitetty kenttä 'user' -> 'liker'

class SignupSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    first_name = serializers.CharField(required=False, allow_blank=True)
    last_name = serializers.CharField(required=False, allow_blank=True)

    class Meta:
        model = User
        fields = ['username', 'password', 'email', 'first_name', 'last_name']

    def create(self, validated_data):
        user = User(
        username=validated_data['username'],
        email=validated_data['email'],
        first_name=validated_data.get('first_name', ''),  # Oikea tapa käyttää get()
        last_name=validated_data.get('last_name', '')     # Oikea tapa käyttää get()
    )
        user.set_password(validated_data['password'])
        user.save()
        return user

URLS.PY

# main/urls.py

from rest_framework.routers import DefaultRouter
from .api_views import CommentViewSet, LikeViewSet,UserViewSet, login_view, logout_view ,PostViewSet
from django.urls import path, include
from . import api_views
from .api_views import csrf_token_view  #,PostCreateView

# REST API reititys
router = DefaultRouter()
router.register(r'posts', PostViewSet)
router.register(r'comments', CommentViewSet)
router.register(r'likes', LikeViewSet)
router.register(r'users', UserViewSet)
    
# URLS
urlpatterns = [
    # REST API reitit
    path('api/', include(router.urls)),
    path('api/login/', login_view, name='api_login'),
    path('api/logout/', logout_view, name='api_logout'),
    path('api/csrf/', csrf_token_view, name='csrf-token'),
    path('api/profile/', api_views.user_profile_view, name='user-profile'),
    path('api/signup/', api_views.signup, name='signedup'),
    #feed
    #path('', views.feed, name='feed'),
]

#ok
django postgresql azure rest django-rest-framework
1个回答
0
投票

我尝试了你的代码并遇到了同样的问题。我发现这个链接解释了如何使用 Django REST 框架部署和创建 REST API。

使用以下命令设置 REST API 后端后:

django-admin startproject ProjectName
cd ProjectName
django-admin startapp ProjectName_api

我在

todo/settings.py
中进行了以下更改,并引用了上面链接中的代码。

ALLOWED_HOSTS = ["*"]

删除 settings.py 中的

CORS_ALLOWED_ORIGINS
CSRF_TRUSTED_ORIGINS

然后,将

'rest_framework'
和您的应用 (
'APIName_api'
) 添加到
INSTALLED_APPS
中的
todo/settings.py
部分:

INSTALLED_APPS = [

    'rest_framework',
    'todo_api',
]

接下来,为

api/models.py
中的待办事项列表创建模型,并定义一个序列化器以将
Todo
模型转换为
api/serializers.py
中的 JSON 格式。

定义用于在

api/views.py
中列出、创建、更新和删除待办事项的 API 视图。然后,在
api/urls.py
:

中定义 API 端点的 URL 模式
urlpatterns = [
    path('api/', TodoListApiView.as_view()),
    path('api/<int:todo_id>/', TodoDetailApiView.as_view()),
]

然后通过编辑

_api
:
ProjectName/urls.py

URL 包含在主项目中
urlpatterns = [ path('admin/', admin.site.urls), path('Url/', include('ProjectName_api.urls')), ]

我按照此链接将Azure PostgreSQL DB与Django集成。首先,创建一个 Azure PostgreSQL 实例,Azure PostgreSQL 数据库的连接字符串将具有以下格式:

dbname=<db_name> host=<db_host> port=5432 user=<db_user> password=<db_password>

将以下内容添加到

settings.py
并更新以下参数:

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('DBNAME'),
        'HOST': os.environ.get('DBHOST'),
        'USER': os.environ.get('DBUSER'),
        'PASSWORD': os.environ.get('DBPASS'),
        'OPTIONS': {'sslmode': 'require'},
    }
}

迁移数据库,创建超级用户,并在本地启动服务器进行测试。然后,将代码推送到 Git。您可以在

todos/api
测试您的 API。

使用 GitHub 创建一个 Web,通过设置持续部署和基本身份验证启用操作。确保在环境变量 azure web 应用程序中添加 PostgreSQL 参数。

按如下方式更新您的

.yml
文件:

     - name: Run Django makemigrations and migrate
        run: |
          source venv/bin/activate
          python manage.py makemigrations
          python manage.py migrate
        env:
          DBNAME: postgres
          DBHOST: AzureHost
          DBUSER: postgres
          DBPASS: postgres

      - name: Create Django superuser
        run: |
          source venv/bin/activate
          python manage.py createsuperuser --noinput --username admin1 --email [email protected]
        env:
          DBNAME: postgres
          DBHOST: AzureHost
          DBUSER: postgres
          DBPASS: postgres

输出:

enter image description here

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.