4👍
To enable the router just add it to DATABASE_ROUTERS
in your setting.py
, see detailes here: https://docs.djangoproject.com/en/1.9/topics/db/multi-db/#using-routers
Every router method gets hints
dictionary, which should contain instance
key representing the model instance being used. Depending on what information you want to get from the view, you might be good with the information from instance attributes. See here: https://docs.djangoproject.com/en/1.9/topics/db/multi-db/#topics-db-multi-db-hints.
I.e.:
def db_for_read(self, model, **hints):
model_instance = hints.get('instance')
if model_instance is not None:
pass
#perform actions with model_instance attributes
return None
Other then this I don’t think there’s other straight way to pass information from the active view to the router, as routers are supposed to work with models and make decisions based on models being used.
DB routers are used for automatic DB selection in models layer, but model methods allow to select the DB manually. See examples here: https://docs.djangoproject.com/en/1.9/topics/db/multi-db/#manually-selecting-a-database
So the other solution is to redefine methods of your form class, i.e. save()
(see https://docs.djangoproject.com/en/1.9/topics/forms/modelforms/#the-save-method), and save the form data manually specifying the DB to use with using
argument. I.e.:
class ProductForm(ModelForm):
class Meta:
...
def save(self, commit=True):
product_to_save=super(ProductForm, self).save(commit=False)
#the above creates product_to_save instance, but doesn't saves it to DB
product_to_save.save(using=='banco1')
return product_to_save
In the comments I suggested to subclass the field that needs to be validated against the other DB, but there’s probably even easier way… Since it’s FK field it’s probably the instance of ModelChoiceField
which accepts the queryset
argument in constructor, so you could provide it, i.e.:
class ProductForm(ModelForm):
category_field = forms.ModelMultipleChoiceField(queryset=Category.objects.using('banco1'))
...
See: https://docs.djangoproject.com/en/1.9/ref/forms/fields/#fields-which-handle-relationships
Answer to EDIT2
The way you redefined the constructor your database
argument gets request.POST
and request.session['database']
is not mapped to anything, that’s why you get the error.
You should account for other arguments and also call superclass constructor or you’ll break the MRO, so something like this should do the job:
class ProductForm(ModelForm):
...
def __init__(self, *args, db_to_use='default', **kwargs):
super(ProductForm, self).__init__(*args, **kwargs)
#category = forms.ModelChoiceField(queryset=Category.objects.using(db_to_use).all())
#the below line suggested as improvement by Alasdair and confirmed as working by Pavarine, so I updated the answer here
self.fields['category'].queryset = Category.objects.using(database).all()
and then as usual, but use named argument:
product_form = ProductForm(request.POST, db_to_use=request.session['database'])