Django Rest Framework:从 URL 参数动态设置数据库
Posted
技术标签:
【中文标题】Django Rest Framework:从 URL 参数动态设置数据库【英文标题】:Django Rest Framework: set database dynamically from URL parameter 【发布时间】:2016-04-13 10:35:09 【问题描述】:我正在尝试找到正确的方法:
用户服务:
/api/<country>/users
/api/us/users
该服务应使用与 URL 中国家/地区对应的数据库。
settings.py:
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',
将 ModelViewSet I 中的数据库设置为:
class UserViewSet(viewsets.ModelViewSet):
model = User
serializer_class = UserSerializer
def get_queryset(self):
country = self.kwargs['country']
return User.objects.using(country).all()
当我尝试执行 POST 或 PUT 时出现问题。我是否必须覆盖序列化程序的 create() 或 save() 方法?有没有其他方法可以做到这一点?
非常感谢!
【问题讨论】:
你现在有什么问题? 我正在尝试找到在创建/保存时设置数据库的方法,就像 get_queryset 中的“使用”函数一样。 【参考方案1】:谢谢亚历克斯!你的回答对我帮助很大。要完全解决问题,我必须这样做:
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
问题就解决了!非常感谢。
【讨论】:
【参考方案2】:我认为此类功能的最佳位置是QuerySet
或ModelManager。例如,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()
【讨论】:
我只是想知道,答案是否解决了您的问题?如果没有,请与我们分享您的解决方案,以完成这篇文章。如果是,请考虑将其标记为已接受,以便其他人可以依赖它。以上是关于Django Rest Framework:从 URL 参数动态设置数据库的主要内容,如果未能解决你的问题,请参考以下文章
从 Django django-rest-framework 视图有条件地返回 JSON 或 HTML 响应
Django REST Framework Serializer和JSONRenderer编码
从 Django Rest Framework 响应中删除空字段
如何从 django-rest-framework 中的文件列表中过滤图像