Shared models between two Django projects and ForeignKey to a model that exists only in one of them

Viewed 197

I have two Django projects that communicate with each other. The first one contains model A and B that has a ForeignKey to A. The first project sends and receives serialized B objects from the second project. I want the second project to contain just B, but it needs the value of that ForeignKey. These models are defined as follows:

class A(models.Model):
    ...

class B(models.Model):
    fk = models.ForeignKey(to='A', on_delete=models.PROTECT)
    ...

The problem is that ForeignKey to A in model B requires model A to be defined in the second project. Its objects also have to exist so that the database is consistent and there are no problems, e.g., in the admin panel.

In the end, I'd like to treat the fk field as a full-fledged ForeignKey in the first project and as some kind of read-only generic identifier in the second one. Specifically, I need to retain the functionality of querying both ways in the first project, e.g., fk__some_a_field and b_set. I would like to have the same code base for the model in both projects to ensure databases in the two projects stay synchronized. How can I achieve this in a clean way?

EDIT: I was also considering fk = CustomField(...) which would be more or less defined as

if IS_FIRST_PROJECT:
    CustomField = ForeignKey
else:
    CustomField = IntegerField

but the issue is that I'd need a clean way to select the type of integer field that exactly matches the default foreign key. Also, I am not sure if such a solution could bring unexpected problems.

1 Answers

Specifically, I need to retain the functionality of querying both ways in the first project, e.g., fk__some_a_field and b_set.

If you want to use django orm, you would have to recreate your A model from project 1 in project 2. But as model A is managed by the project 1, consider adding next lines to your model in project 2:

class A(models.Model):
    ...
    
    class Meta:
        managed = False
        db_table = 'your database table name where A model is stored'

managed=False would tell django to ignore migrations for it, and django won't be allowed to change that model's database table.

The other solution if you don't want to duplicate models from project 1 to project 2, is to not use django orm. And write sql queries by yourself. But as you mentioned you don't want to do this

P.S if you don't know how to see name of database table for model A, you can output it like this: a_model_instance._meta.db_table, or look it in some tools like pgadming if you are using postgres

Related