class ItemAdmin(admin.ModelAdmin):
# A handy constant for the name of the alternate database.
using = 'other'
def save_model(self, request, obj, form, change):
# Tell Django to save objects to the 'other' database.
obj.save(using=self.using)
def delete_model(self, request, obj):
# Tell Django to delete objects from the 'other' database
obj.delete(using=self.using)
def get_queryset(self, request):
# Tell Django to look for objects on the 'other' database.
return super().get_queryset(request).using(self.using)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
# Tell Django to populate ForeignKey widgets using a query
# on the 'other' database.
return super().formfield_for_foreignkey(db_field, request, using=self.using, **kwargs)
def formfield_for_manytomany(self, db_field, request, **kwargs):
# Tell Django to populate ManyToMany widgets using a query
# on the 'other' database.
return super().formfield_for_manytomany(db_field, request, using=self.using, **kwargs)
foreign key validation throwing error because of
django\db\models\fields\related.py
def validate(self, value, model_instance):
if self.remote_field.parent_link:
return
super().validate(value, model_instance)
if value is None:
return
using = router.db_for_read(self.remote_field.model, instance=model_instance)
qs = self.remote_field.model._base_manager.using(using).filter(
**{self.remote_field.field_name: value}
)
so how to validate remote field using ‘other’ database?(‘other’ is based on request)
Is it a bug?
Side note: In the future, when you’re posting code or traceback messages, surround the code (or traceback) between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code, then another line of ```. (I’ve made the edit for you this time.)
Also, please post the complete traceback error you’re getting as a result of this.
sorry for inconvenience.
the error message in page is
“measuring unit instance with id 1 does not exist.”
because in router.py
db_for_read
return ‘default’
who has no measuring unit record.
So foreign key vaildation is breaking same database relation
Your console log where you’re running runserver should have the more complete traceback message. Or, if this is a production deployment and you’re not using runserver, then your server logs should have it as well.
The implementation provided here implements a multi-database strategy where all objects of a given type are stored on a specific database (e.g., all User objects are in the other database). If your usage of multiple databases is more complex, your ModelAdmin will need to reflect that strategy.
Are all Item and MeasuringUnit in the same database, or do you have multiple databases, each with different sets of Item and MeasuringUnit?
I have multiple databases, each with different sets of Item and MeasuringUnit
i don’t have any traceback message because error is handled by django validation error
def validate(self, value, model_instance):
if self.remote_field.parent_link:
return
super().validate(value, model_instance)
if value is None:
return
using = router.db_for_read(self.remote_field.model, instance=model_instance)
qs = self.remote_field.model._base_manager.using(using).filter(
**{self.remote_field.field_name: value}
)
qs = qs.complex_filter(self.get_limit_choices_to())
if not qs.exists():
raise exceptions.ValidationError(
self.error_messages["invalid"],
code="invalid",
params={
"model": self.remote_field.model._meta.verbose_name,
"pk": value,
"field": self.remote_field.field_name,
"value": value,
}, # 'pk' is included for backwards compatibility
)
This is the hard part of multiple databases in django, because the user is selecting the database at login and router doesn’t aware of request (the database is stored in cookie).
If there is a solution to handle this…
Off the top of my head, I can think of a couple of different ways to handle this. None necessarily straight forward, but I think they all are workable.
Don’t use the Admin for this. You’re really in an area that the Django Admin isn’t set up to handle. If you create your own views, you’re going to have more control over the databases being used for the entire process - including having access to the using attribute of the queryset used to retrieve the data.
Subclass ForeignKey with a custom validate method, and have your models use your custom subclass as the ForeignKey field.
Create a custom manager that annotates the name of the database into the instances being retrieved. This would allow you to use a router with the instance hint to handle the relationship.