虽然使用django restframework多个数据库,serializer.is_valid()总是去默认数据库进行验证

问题描述:

我使用django restframework并希望处理多个数据库。我使用django函数使用(别名)和switch_db(别名)在我想要获取,发布或更新数据时手动在数据库之间切换。虽然使用django restframework多个数据库,serializer.is_valid()总是去默认数据库进行验证

我在发布和更新data.i.e时遇到问题,只要调用serializer.is_valid()。

serializer.is_valid()将继续并首先检查model.py文件中的db_alias。如果我没有在meta下指定db_alias,它将选择默认数据库进行验证。如果我在模型中指定db_alias,它将选择该数据库进行验证。

但我不想在模型中指定db_alias,因为我的用例是基于我的视图文件中的一些逻辑将数据存储在不同的数据库上。所以动态我想从视图中选择数据库,并希望在其中存储数据。

几乎我已经实施,但我面临的问题是当我的模型有参考字段。在这种情况下,serializer.is_valid将默认数据库来验证该引用字段。

需要的详细信息:我正在使用mongoengine(0.9.0),文档,文档序列化程序。

我的文件如下:

model.py:

class ngroup(Document): 

    groupname = StringField(max_length=100, required=True) 
    description = StringField(max_length=100, required=False) 
    parent = ReferenceField('ngroup',null=True) 
    created_ts = DateTimeField(default=datetime.now()) 
    modified_ts = DateTimeField(default=datetime.now()) 
    is_deleted = BooleanField(default=False) 

serializer.py:

from device_management.models import ngroup 
from rest_framework_mongoengine.serializers import DocumentSerializer 
from mongoengine import EmbeddedDocumentField, ReferenceField, StringField, ObjectIdField, IntField, BooleanField, FloatField, DateTimeField,ListField 


class ngroupSerializer(DocumentSerializer): 

    class Meta: 
     model = ngroup 

    def setOrgId(self, orgid): 
     self.orgid = orgid 

    def create(self, validated_data): 
     ngroup_data = ngroup(**validated_data).switch_db(self.orgid) 
     ngroup_data.save() 
     return ngroup_data 

    def update(self, instance, validated_data): 
     ngroup_data = ngroup.objects.using(self.orgid).get(id = instance.id) 
     ngroup_data = ngroup_data.switch_db(self.orgid) 
     ngroup_data = ngroup_data.update(**validated_data) 
     return validated_data 

    def to_internal_value(self, data): 
     print "data:" , data 
     return super(DocumentSerializer, self).to_internal_value(data) 

view.py:

def create(self, request, format=None): 
    orgid = str(request.user.orgid.id) 
    data=request.data 

    serializer = ngroupSerializer(data=data) 
    if serializer.is_valid(): 
     try: 
      serializer.save() 
     except Exception as e: 
      log.error("create" , extra={'extra':{'error': str(e),'message' :strings.DATA_VALIDATION_ERROR }}) 
      return response.errorResponse(message=strings.SERIALIZATION_ERROR_MSG,error=str(e),rstatus=status.HTTP_400_BAD_REQUEST) 
     return response.successResponse(res_data=serializer.data, message=strings.POST_SUCCESS_MSG, rstatus=status.HTTP_201_CREATED) 
    log.error("create" , extra={'extra':{'error': serializer.errors,'message' :strings.DATA_VALIDATION_ERROR }}) 
    return response.errorResponse(message=strings.DATA_VALIDATION_ERROR,error=serializer.errors,rstatus=status.HTTP_400_BAD_REQUEST) 

settings.py :

DATABASES = { 
    'default': { 
     'ENGINE': 'django_mongodb_engine', 
     'NAME': 'mydb', 
     'USER': 'admin', 
     'PASSWORD':'admin123', 
     'HOST': '127.0.0.1', 
     'PORT': 27017, 
     'DBTYPE' : "mongo", 
    }, 
    '586e47c784413825f2b5bc49': { 
     'ENGINE': 'django_mongodb_engine', 
     'NAME': 'mydb1', 
     'USER': 'admin', 
     'PASSWORD':'admin123', 
     'HOST': '127.0.0.1', 
     'PORT': 27017, 
     'DBTYPE' : "mongo", 
    }, 
    # Enter super_user organisation here. This DB will be same as default db only always 
    '58996fb28441384430dc8ae6': { 
     'ENGINE': 'django_mongodb_engine', 
     'NAME': 'mydb', 
     'USER': 'admin', 
     'PASSWORD':'admin123', 
     'HOST': '127.0.0.1', 
     'PORT': 27017, 
     'DBTYPE' : "mongo", 
    }, 
} 

PIP冻结(安装的版本):

Django==1.5.11 
django-browserid==2.0.2 
django-classy-tags==0.8.0 
django-missing==0.1.18 
django-mongo-auth==0.1.3 
django-mongodb-engine==0.6.0 
django-mongoengine==0.2.1 
django-redis-sessions==0.5.6 
django-rest-framework-mongoengine==3.3.0 
django-sekizai==0.10.0 
django-websocket-redis==0.4.7 
djangorestframework==3.1.2 
djangorestframework-jwt==1.9.0 
djangotoolbox==1.8.0 
gevent==1.1.2 
greenlet==0.4.10 
httplib2==0.9.2 
mongoengine==0.9.0 
oauthlib==2.0.1 
pika==0.10.0 
Pygments==2.1.3 
PyJWT==1.4.2 
pymongo==2.8 
python-dateutil==2.6.0 
python-openid==2.2.5 
pytz==2016.10 
redis==2.10.5 
requests==2.12.3 
requests-oauthlib==0.7.0 
rest-condition==1.0.3 
six==1.10.0 
tweepy==3.5.0 
twilio==5.7.0 

我在串行已经超越控制创造采取数据库的照顾,同时调用serializer.save(),但如何处理serializer.is_valid()。

我的项目一直卡在这一点。任何帮助将不胜感激...

侯赛因,

不幸的是,你是不兼容的项目混合在一起。 Mongoengine,django-mongoengineDjango-REST-Framework-Mongoengine项目是django-mongodb-engine的替代项,它们并不意味着一起使用。

据我所知,django-mongodb-engine项目已被dead for 2 years,甚至更长,说实话。与此同时,Mongoengine堆栈正在生产中,但是,开发并不太活跃。我真的很想在Mongoengine中创建一个合适的django数据库后端,使它成为Django世界中的头等公民,并且它是seems like Django guys are looking in that direction, too。您可能还想看看this post

这是我第二次尝试。我试图切换数据库连接的视图create()。没有为我工作:

settings.py

# We define 2 Mongo databases - default (project) and project2 
MONGODB_DATABASES = { 
    "project": { 
     "name": "project", 
     "host": "localhost", 
     "port": 27017, 
     "tz_aware": True, # if you use timezones in django (USE_TZ = True) 
    }, 

    "project2": { 
     "name": "project2", 
     "host": "localhost", 
     "port": 27017, 
     "tz_aware": True, # if you use timezones in django (USE_TZ = True) 
    } 
} 


mongoengine.register_connection(alias='default', name=MONGODB_DATABASES["project"]["name"], host="local") 
mongoengine.register_connection(alias='project2', name=MONGODB_DATABASES["project2"]["name"], host="local") 

connection = mongoengine.connect(db="project", alias='default') 

views.py

class AuthorViewSet(MongoModelViewSet): 
    lookup_field = 'id' 
    serializer_class = AuthorSerializer 

    def create(self, request, format=None): 
     global Author 
     mongoengine.connection.disconnect(alias='project') 
     mongoengine.connect('project2', alias='project2') 
     return super(AuthorViewSet, self).create(request, format) 

    def get_queryset(self): 
     return Author.objects.all() 
+0

嗨鲍里斯, 我可以使用django-mongodb引擎作为数据库后端和模型和modelserializer,而不是文档和文档序列化程序。 –

+0

继续... 即即使我开始使用django-mongodb引擎而不是mongoengine和rest-framework-mongoengine,那么是否会有任何问题。 因为我使用django-mongodb-engine + Modeld.model + Modelserializer和Mongodb作为数据库进行了以下检查。 1)用于数据库切换的数据库路由器。 2)嵌入式模块领域 3)DictField ,事情正在非常好的 –

+0

继续... ,事情正在非常好的 所以,如果我在我的项目移植到模型从文档中,将可以随时随地在阻止我未来。 django-mongodb-engine是否有任何限制? (既然你提到“django-mongodb引擎项目已经死了2年,甚至更长时间了”) –

这并不是上述问题的精确解,但我们有2种选择。

1)不要去serializer.is_valid()或serializer.save()。 直接创建NGROUP:

def my_create(self, validated_data): 
    gateway = Gateway(**validated_data).switch_db(self.orgid) 
    gateway.save() 
    return gateway 

2)另一种解决方案是使用Django的mogodb引擎和Django模型和modelserializers,而不是单据和序列化。

我试图与Django的MongoDB的发动机下面这一点,并正常工作:

-> JWT authentication 
-> custom user 
-> foreign key 
-> embedded model 
-> list of embedded model 
-> dict field 
-> **Routers for switching between databases.(Manual switching DB is not required)** 

我也可以用在MIDDLEWARE_CLASSES使用哪个数据库,每个请求指定运行。 参考链接:Django Authenticate Backend Multiple Databases