2017-02-23 63 views
3

Я использую рефаймер django и хочу обрабатывать несколько баз данных. Я использую функцию django с использованием (alias) и switch_db (alias) для ручного переключения между базами данных всякий раз, когда я хочу получать, отправлять или обновлять данные.При использовании django restframework Несколько баз данных, serializer.is_valid() всегда идут в базу данных по умолчанию для проверки

Перед вызовом и обновлением data.i.e возникает проблема при вызове serializer.is_valid().

serializer.is_valid() отправится и сначала проверит db_alias в файле model.py. Если я не указал db_alias под мета, он будет выбирать базу данных по умолчанию для проверки. Если я задаю db_alias в модели, он выберет эту базу данных для проверки.

Но я не хочу указывать db_alias в модели, так как моя usecase предназначена для хранения данных в разных базах данных на основе некоторой логики в моем файле вида. Поэтому динамически я хочу выбрать базу данных из представления и хочу хранить в ней данные.

Практически я реализовал, но перед тем как столкнуться с проблемой, когда у моей модели есть Reference Field. В этом случае 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", 
    }, 
} 

пип замораживание (версии Установки):

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 

Я overide создать в сериализаторе заботиться базами данных при вызове serializer.save(), но, как обращаться serializer.is_valid().

В данный момент мой проект застрял. Любая помощь будет принята с благодарностью ...

ответ

0

Хусайн

К сожалению, вы смешиваете несовместимые проекты вместе. Mongoengine, django-mongoengine и Django-REST-Framework-Mongoengine проекты являются альтернативой django-mongodb-engine, они не предназначены для использования вместе.

Насколько я знаю, django-mongodb-engine Проект был dead for 2 years, или даже дольше, если быть честным. В то же время, Mongoengine стек работает в производстве, хотя разработка не слишком активна. Я действительно хочу создать надлежащую базу данных базы данных django из Mongoengine, чтобы сделать ее первоклассным гражданином в мире 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

Hi Boris, Могу ли я использовать django-mongodb-engine в качестве базы данных, а также модель и modelerializer вместо документа и сериализатора документов. –

+0

continue ... i.e Если я начну использовать django-mongodb-engine вместо mongoengine и rest-framework-mongoengine, это может вызвать проблемы. Потому что я проверил следующие вещи с помощью django-mongodb-engine + Modeld.model + Modelserializer и Mongodb в качестве базы данных. 1) Маршрутизаторы баз данных для переключения базы данных. 2) Встроенное поле Модели 3) DictField и все работают очень хорошо –

+0

продолжить ... и все работают очень хорошо Так что, если я перенесу мой проект модели из документов, будет, что может остановить меня в любом месте будущее. Существуют ли какие-либо ограничения на двигатель джанго-монгоба? (Поскольку вы упоминаете, что проект django-mongodb-engine был мертв в течение 2 лет или даже дольше ») –

1

Это не точное решение указанной проблемы, но у нас есть 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) Другим решением является использование моделей Джанго-mogodb-двигателя и Джанго и 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

Смежные вопросы