To take advantage of Django Admin, you need to make a model first, no matter from where it fetches data.
Now, since we are mapping the model to DB, you could either make the model based on a DB view, or any one of the three tables(user1.table1, user2.table2 and user3.table3):
Base on DB view:
First, create a DB view to take col1
, col2
and col3
from tables.
Also, choose a primary key for the model: it could be any (including extra) column in the DB view, as long as the model field w/ primary_key=True
matches the column, here I simply choose col1
.
# use Sqlite to create view, Oracle could be similar
CREATE VIEW view_for_legacy_tables AS SELECT t1.col1, t2.col3, t3.col2 from user1.table1 t1, user2.table2 t2, user3.table3 t3 where t1.col1 = t2.col2 AND t2.col2 = t3.col3;
# in model
class Foo(models.Model):
col1 = models.TextField(primary_key=True)
col2 = models.TextField()
col3 = models.TextField()
class Meta:
db_table = 'view_for_legacy_tables'
From now on, syncdb
or South migrate
might complain the exists, here simply ignore them.
You could bypass it by faking migration in South or move the model from models.py to other files or functions that does not loaded by models.py.
After define corresponding ModelAdmin for the model Foo
, the Foo
could be displayed in changelist in Django Admin.
If you want to use addview or changeview to do some modification upon the tables, you could override save
method of the Foo
model or customize ModelForm, or customize add_view
/change_view
of the ModelAdmin. The code varies on your actual usage, thus I don't provide one here.
Base on table user1.table1
This works similar as the method based on DB view. To be able to use addview and changeview, you need to customize ModelForm also.
Define the model
class Foo(models.Model):
col1 = models.TextField(primary_key=True)
class Meta:
db_table = 'user1.table1'
Then in admin.py
class FooAdmin(admin.ModelAdmin):
list_display = ('col1', 'col2', 'col3')
def queryset(self, request): # you could customize the default manager of model Foo
qs = super(FooAdmin, self).queryset(request)
return qs.extra(select={'col2':'user2.table2.col2', 'col3':'user3.table3.col3'},
tables=['user2.table2', 'user3.table3'],
where=['col1 = user2.table2.col2', 'user2.table2.col2'='user3.table3.col3']) # or use `raw()`, depends on your columns
def col2(self, obj):
return obj.col2
def col3(self, obj):
return obj.col3
update
The usage is very uncommon, thus I've seen few documents about it. Most relative things could be options.py
inside django/contrib/admin
and the implementation of Model inside django/db/models/base.py
.
If you want to achieve SELECT * from t1, t2, t3 where ... like '%?%'", [var1])
, the easiest way probably is to write your own view by using Admin UI, just as https://github.com/dmpayton/django-mongoadmin
If var1
of SELECT * from t1, t2, t3 where ... like '%?%'", [var1])
is determined, you could make several models for each value of var1
; if its not, you have to do some dynamic way about model and admin, just ref Django dynamic model fields , which could be even harder IMO.