1

I'm trying to find the right way to do this:

Users service:

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

That service should use the database corresponding to the country in the 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',
}  }

To set the database in the ModelViewSet I to this:

class UserViewSet(viewsets.ModelViewSet):

    model = User
    serializer_class = UserSerializer

    def get_queryset(self):
        country = self.kwargs['country']
        return User.objects.using(country).all()

The problem appears when I try to do a POST or PUT. Do I have to overwrite the create() or save() method of the serializer? Is there any other way to do this?

Thank you very much!

2
  • what's your problem now? Commented Jan 8, 2016 at 17:01
  • I'm trying to find the way to set the database on create/save like the "using" function in get_queryset. Commented Jan 8, 2016 at 17:26

2 Answers 2

3

I think the best place for such functionality is a QuerySet or a ModelManager. For example, the DRF's default serializer uses the default model's manager for creating objects. Unfortunately, the QuerySet doesn't have a way to easily change the current database (self.db) depending on the models' fields, so you'll have to override all the relevant methods.

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()
Sign up to request clarification or add additional context in comments.

1 Comment

I'm just wondering, did the answer solve your problem? If not, please share your solution with us to make this post complete. If yes, consider marking it as accepted, so that the others can rely on it.
0

Thank you Alex! You answer help me a lot. To fully solve the problem I have to do this:

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)

And then in the 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

And the problem is solved! Thank you a lot.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.