foreign key validation error multiple databases

class MeasuringUnit(models.Model):
    MeasuringUnitCode = models.CharField('Code', max_length=15)
    MeasuringUnitName = models.CharField('Name', max_length=50)

class Item(models.Model):
    MeasuringUnitId =  models.ForeignKey(MeasuringUnit, on_delete=models.CASCADE)
    ItemCode = models.CharField('Code', max_length=100)
    ItemName = models.CharField('Name', max_length=364)

admin.py

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.

Also note from the docs at Multiple databases | Django documentation | Django

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
           )

You’ve shown your Admin class, how about your database router?

I would think you can handle this by having your custom router return the right db for the instance of the model being validated.

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.