如何将记录保存到正确的架构/租户?

时间:2019-03-22 20:36:55

标签: django django-rest-framework multi-tenant

我正在使用django-tenant-schemas在Django中处理多租户应用程序。但是,当我保存用户时,他们似乎没有正确地与其租户联系在一起。当查询租户上的用户列表时,我会获得数据库中所有用户的列表。我可以看到这些记录具有正确的外键,但是它们似乎都集中在同一模式中。

我浏览了这个Multi-tenant schema with django和这个User doesn't exists and no redirect to created tenant in django project,但我无法正常工作

这是我的租户模型(estates / models.py):

from django.db import models
from tenant_schemas.models import TenantMixin
from .managers import EstateManager


# Create your models here.
class Estate(TenantMixin):
    name = models.CharField(max_length=100, unique=True)
    slug = models.CharField(max_length=20, unique=True)
    is_active = models.BooleanField(default=True)
    created_on = models.DateField(auto_now_add=True)

    auto_create_schema = True

    objects = models.Manager()
    tenancy = EstateManager()

这是我的自定义用户模型(authentication / models.py):

from django.core.mail import send_mail
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser
from estates.models import Estate
from .managers import UserManager


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField('email address', unique=True)
    phone = models.CharField('phone', max_length=50)
    first_name = models.CharField('first name', max_length=100)
    last_name = models.CharField('last name', max_length=100)
    created_at = models.DateTimeField('date created', auto_now_add=True)
    is_active = models.BooleanField('active', default=True)
    is_owner = models.BooleanField('is owner', default=True)
    is_security = models.BooleanField('is security', default=False)
    is_resident = models.BooleanField('is resident', default=False)
    estate = models.ForeignKey(Estate, on_delete=models.SET_NULL, related_name='people', null=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    class Meta:
        verbose_name = 'user'
        verbose_name_plural = 'users'
        unique_together = ('phone', 'estate',)

这是我的序列化器和视图:

class SignupSerializer(serializers.ModelSerializer):
    estate = EstateSerializer(many=False, required=True)

    class Meta:
        model = User
        fields = ('id', 'first_name', 'last_name', 'phone', 'email', 'password', 'estate')
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        estate = validated_data.pop('estate')

        # save estate
        e = Estate.tenancy.create_estate(name=estate['name'], slug=estate['slug'])
        e.save()

        with schema_context(e.schema_name):
            user = User(**validated_data)
            user.set_password(validated_data['password'])
            user.estate = e
            user.save()

            # create user token for rest authentication
            Token.objects.create(user=user)

        return user

class SignupView(viewsets.generics.CreateAPIView):
    serializer_class = SignupSerializer
    permission_classes = ()
    authentication_classes = ()
    queryset = User.objects.all()

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)

        return Response(serializer.data, status=status.HTTP_201_CREATED)

这是我的设置文件:

ALLOWED_HOSTS = ['*']

# Application definition

SHARED_APPS = [
    'tenant_schemas',
    'estates',
    'rest_framework',
    'authentication',
    'rest_framework.authtoken',
    'safedelete',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

TENANT_APPS = [
    # The following Django contrib apps must be in TENANT_APPS
    'django.contrib.contenttypes',
    'core',
]

INSTALLED_APPS = SHARED_APPS + [app for app in TENANT_APPS if app not in SHARED_APPS]

TENANT_MODEL = "estates.Estate"
DEFAULT_FILE_STORAGE = 'tenant_schemas.storage.TenantFileSystemStorage'

0 个答案:

没有答案