Reputation: 2552
I've currently got existing tables in my database that were created with models as per the usual way (using makemigrations
and migrate
).
Now, I am looking to combine certain data from these existing tables, without having to create a new table in my database. Then, I would like to serialise that data to make it accessible via the views APIs.
My understanding is that I create an unmanaged model to handle this. I understand as part of the docs that you need to specify managed = False
but that's just a start. So far, I've literally only found one link (that isn't very helpful): https://riptutorial.com/django/example/4020/a-basic-unmanaged-table-
Let's say hypothetically, I've got user information that is inputted in many different tables in my existing database and I'd like to create certain data points within my new and unmanaged model to combine it into one serialiser. As of now, this is what I've come up with. Note that in my user model, I don't know what to specify for my db_tables
parameter since, like I mentioned, data will be coming from many different tables, not just one.
UserModel
from django.db import models
class UserModel(models.model):
user = models.CharField(db_column="LABEL", max_length=255)
class Meta:
managed = False
db_table = "Sample_Table_1"
UserSerializer
from rest_framework import serializers
from models.user import UserModel
class UserSerializer(serializer.ModelSerializer):
class Meta:
model = UserModel
fields = "__all__"
UserViewSet
from rest_framewirk.viewsets import ModelViewSet
from models.user import UserModel
from serializers.user import UserSerializer
class UserViewSet(ModelViewSet):
queryset = UserModel.objects.all()
serializer_class = UserSerializer
def list(self, request **kwargs):
return super(UserViewSet, self).list(request)
Where do I go from here if I wanted to get another data point from a different table other than db_table = "Sample_Table_1"
? For example, if I wanted data from a Sample_Table_2
table?
I think my main issue is that I don't really know how unmanaged models work and how I can retrieve data from different tables that already exist in my database. If anyone can point me to a tutorial that can help me with that, it would be a good start.
Upvotes: 4
Views: 3324
Reputation: 138
if you want to return data from different model to a single api call one way to achieve this is to user serializers.Serializer
class TestClass(serializers.Serializer):
table1 = serializers.IntegerField()
......
and you can use this class for serialization.
Upvotes: 1
Reputation: 1551
If you want to combine data from different tables, you can try with a DB view. and put an unmanaged model in front of it. for example:
class UserModel(models.Model):
user = models.CharField(db_column="user", max_length=255)
class Meta:
managed = False
db_table = "sample_table_1"
Inside the migration file create a DB view (assuming Postgres) with a RunSQL
class Migration(migrations.Migration):
dependencies = [
('accounts', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='UserModel',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('user', models.CharField(db_column='user', max_length=255)),
],
options={
'db_table': 'sample_table_1',
'managed': False,
},
),
migrations.RunSQL(
sql="""
CREATE OR REPLACE VIEW sample_table_1 AS
SELECT id, username AS user FROM auth_user;
# Here I used <username> as an example
""",
reverse_sql="""
DROP VIEW IF EXISTS sample_table_1;
"""
)
]
class UserModelSerializer(serializers.ModelSerializer):
class Meta:
model = UserModel
fields = '__all__'
useful links: https://www.fusionbox.com/blog/detail/using-materialized-views-to-implement-efficient-reports-in-django/643/
https://schinckel.net/2020/03/03/postgres-view-from-django-queryset/
Upvotes: 3
Reputation: 21822
If one already has tables in the database one should generally use the inspectdb
[Django docs] management command to generate atleast the basic structure of these tables as models, you might need to fix some things that Django is not able to infer properly. You would (after configuring the database settings properly) run the following command, which will atleast get you started on making the correct models:
python manage.py inspectdb
In general you should refer to the Integrating Django with a legacy database section of the documentation.
Moving further, you seem to haven't set the proper table name for your model (since it exists already, it's name might be different from what Django will generate), so if you want a manual fix, you would set the db_table
[Django docs] attribute in the model's Meta
:
class UserDetails(models.model):
user = models.CharField(db_column="LABEL", max_length=255)
class Meta:
managed = False
db_table = '<YOUR_TABLE_NAME_HERE>'
Upvotes: 1