簡體   English   中英

如何讓 Django Rest Framework 與 Django Tenants 和 React 一起使用?

[英]How can I get Django Rest Framework to work with Django Tenants and React?

這是我的設置:

設置.py

SHARED_APPS = (
    'django_tenants',
    'main',
    other apps...
)

TENANT_APPS = (
    'rest_framework',
    'company',
)

MIDDLEWARE = [
    'django_tenants.middleware.main.TenantMainMiddleware',
    other middleware...
]

DATABASE_ROUTERS = (
    'django_tenants.routers.TenantSyncRouter',
)

網址.py

from django.urls import include, path
from rest_framework import routers

# other imports

from main.api.v1 import projects

router = routers.DefaultRouter()
router.register(r'api/v1/project', projects.ProjectViewSet)

urlpatterns = [
    -- other paths --
    path('', include(router.urls)),
]

api/v1/project.py

# other imports
from company.models import Project

from rest_framework import serializers
from rest_framework import viewsets
from rest_framework import permissions

class ProjectSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Project
        fields = ['url', 'name', 'keycode']

class ProjectViewSet(viewsets.ModelViewSet):
    queryset = Project.objects.all().order_by('id')
    serializer_class = ProjectSerializer
    permission_classes = [permissions.AllowAny]

主模型.py

from django.contrib.auth.models import User as AuthUser
from django_tenants.models import TenantMixin, DomainMixin

# note, definition of custom "User" model which has an AuthUser 1 to 1 relationship

class Company(TenantMixin):
    name = models.CharField(max_length=100)
    subdomain = models.CharField(max_length=32)
    employees = models.ManyToManyField(User, related_name='companies')
    migration_id = models.IntegerField(null=True)

class Domain(DomainMixin):
    pass

公司模型.py

from django.db import models

class Project(models.Model):
    name = models.CharField(max_length=100)
    keycode = models.CharField(max_length=8)

最后一個細節是我沒有使用 Django 前端,而是使用 React 創建的前端。 發送到后端的請求只是一個標准請求,但是它來自子域並包含一個 JWT 令牌(但我不知道這是否相關),這是請求標頭的縮短版本:

Request URL: http://localhost:8000/api/v1/project/
Request Method: GET
Authorization: Bearer <token here>
Origin: http://cbd.localhost:3000

我在后端看到的錯誤是這樣的:

關系“company_project”不存在

我的猜測是,這是由於在 ProjectViewSet 中創建此查詢時發生的:

queryset = Project.objects.all().order_by('id')

該請求不是在租戶的上下文中完成的。 但我的問題是這到底是怎么做的。 我在 Django Tenants 中看到有一個看起來像這樣的構造:

with tenant_context(tenant):
    # All commands here are ran under the schema from the `tenant` object

但我不知道如何在似乎需要的類定義中獲取“租戶”參數。

有任何想法嗎?

好吧,我想出了一種方法來做到這一點,但它很難看。

在我的 settings.py 文件中,我添加了一個新常量:

BASE_TENANT = "cbd_co"

我將此設置為我的第一個租戶(在我的系統中,將有一個默認租戶架構,它實際上並不由客戶擁有,而是一種模板)

然后,在我的模型視圖聲明中,我這樣做了:

class ProjectViewSet(viewsets.ModelViewSet):
    queryset = Project.objects.raw('SELECT * FROM "' + settings.BASE_TENANT + '"."company_project";')
    serializer_class = ProjectSerializer
    permission_classes = [permissions.AllowAny]

    def get_queryset(self):
        schema = self.request.META['HTTP_ORIGIN'].split("//")[1].split('.')[0] + '_co'
        qs = Project.objects.raw('SELECT * FROM "' + schema + '"."company_project" ORDER BY "company_project"."id" ASC;')
        return qs

我仍然希望有人提出更好的解決方案......

有關此解決方案的說明。 事實上,它是完全不安全的。 我實際上要做的是從請求中獲取授權標頭,驗證 JWT 令牌,獲取用戶,獲取所有有效的用戶公司(這也確定了有效的子域,因此也確定了有效的模式。然后我才會返回查詢集。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM