Django Rest Framework:从URL参数动态设置数据库

时间:2016-01-08 16:57:43

标签: python django database django-rest-framework

我试图找到正确的方法来做到这一点:

用户服务:

Tabbed Document

该服务应使用与URL中的国家/地区对应的数据库。

settings.py:

/api/<country>/users
/api/us/users

要将ModelViewSet I中的数据库设置为:

DATABASES = {
'default': {},
'us': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'XXX_US', 
    'USER': 'US',
    'PASSWORD': 'XXX',
    'HOST': 'localhost',
    'PORT': '5432',
},
'es': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'XXX_ES', 
    'USER': 'ES',
    'PASSWORD': 'XXX',
    'HOST': 'localhost',
    'PORT': '5432',
}  }

当我尝试执行POST或PUT时会出现问题。我是否必须覆盖序列化程序的create()或save()方法?还有其他办法吗?

非常感谢!

2 个答案:

答案 0 :(得分:3)

我认为此类功能的最佳位置是QuerySetModelManager。例如,DRF的默认序列化程序使用the default model's manager来创建对象。遗憾的是,QuerySet无法根据模型的字段轻松更改当前数据库(self.db),因此您必须覆盖所有相关方法。

class UserQuerySet(models.QuerySet):
    def create(self, **kwargs):
        obj = self.model(**kwargs)
        self._for_write = True
        obj.save(force_insert=True, using=kwargs.get('country'))
        return obj

class User(models.Model):
    objects = UserQuerySet.as_manager()

答案 1 :(得分:0)

谢谢Alex!你回答帮我很多。要完全解决问题,我必须这样做:

views.py

class UserViewSet(viewsets.ModelViewSet):

    model = User
    serializer_class = UserSerializer

    def perform_create(self, serializer):        
        serializer.validated_data['country'] = self.kwargs.get('country')
        serializer.create(serializer.validated_data)

然后在models.py中:

class UserQuerySet(models.QuerySet):

    def create(self, **kwargs):
        country = kwargs.get('country')  #Get the country
        kwargs.pop('country')            #Pop the country from kwargs
        obj = self.model(**kwargs)
        self._for_write = True                
        obj.save(force_insert=True, using=country)
        return obj

class User(models.Model):

    objects = UserQuerySet.as_manager()
    id = models.AutoField(primary_key=True,db_column='user_id')
    name = models.CharField(max_length=40)

    class Meta:
        managed = True
        db_table = Constants().USER

问题解决了!非常感谢你。