I have a PostgreSQl database with three main tables: houses, searches for those houses and users making the searches.
The houses have characteristics, e.g. an address and price, a user can search multiple times for the same house and in the search give the house a rating.
A House:
[
{
"house_id": "0363200000499764",
"address": "Bos en Lommerplein 104, Amsterdam",
"street": "Bos en Lommerplein"
"city": "Amsterdam",
"price": 700000
},
]
Multiple Searches for the same house by different users:
[
{
"search_id" : 1,
"house_id": "0363200000499764",
"user_id": 1,
"date_searched": "2022-09-07 12:14:14",
"rating": 1
},
{
"search_id" : 2,
"house_id": "0363200000499764",
"user_id": 1,
"date_searched": "2022-10-08 14:00:00",
"rating": 2
},
{
"search_id" : 3,
"house_id": "0363200000499764",
"user_id": 3,
"date_searched": "2022-04-01 09:36:32",
"rating": 4
},
{
"search_id" : 4,
"house_id": "0363200000499764",
"user_id": 2,
"date_searched": "2021-09-08 18:59:10",
"rating": 5
},
]
Users:
[
{
"user_id": 1,
"first_name": "John",
"last_name": "Doe"
},
{
"user_id": 2,
"first_name": "Jane",
"last_name": "Doe"
},
{
"user_id": 3,
"first_name": "Patrick",
"last_name": "West"
},
]
I am using Django and created models for these tables in the database.
Snippet from my models.py file:
from django.db import models
from django.contrib.auth.models import User
class House(models.Model):
house_id = models.CharField(max_length=16, blank=True, unique=True, primary_key=True)
address = models.CharField(max_length=200, blank=True, null=True, verbose_name='Address')
street = models.CharField(max_length=80, blank=True, null=True, verbose_name='Street')
city = models.CharField(max_length=80, blank=True, null=True, verbose_name='City')
price = models.DecimalField(max_digits=1000, decimal_places=2, blank=True, null=True, verbose_name='Price')
class Meta:
managed = False
db_table = 'public"."houses'
verbose_name = 'House'
verbose_name_plural = 'Houses'
def __str__(self):
return self.address
class Search(models.Model):
search_id = models.BigAutoField(primary_key=True)
house = models.ForeignKey(House, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
rating = models.IntegerField(blank=True, null=True)
date_searched = models.DateTimeField()
class Meta:
managed = True
db_table = 'public"."searches'
Now I am using Django REST framework to serialize the data from the database to json fields.
For example, I have created a HouseSerializer that serializes the house data to a json.
Snippet of my serializers.py:
from rest_framework import serializers
from .models import House
class HouseSerializer(serializers.ModelSerializer):
house_id = serializers.CharField(max_length=16)
address = serializers.CharField(max_length=200)
street = serializers.CharField(max_length=80)
city = serializers.CharField(max_length=80)
price = serializers.DecimalField(max_digits=1000)
class Meta:
model = House
fields = ("house_id", "address", "street", "city", "price")
Now I would like to expose all searches per user and show all the house information, including the rating they have given to the house.
So for user 1, the json response should be the following:
[
{
"user_id": 1,
"house_id": "0363200000499764",
"address": "Bos en Lommerplein 104, Amsterdam",
"street": "Bos en Lommerplein"
"house_id": "0363200000499764",
"city": "Amsterdam",
"price": 700000,
"date_searched": "2022-09-07 12:14:14",
"rating": 1
},
{
"user_id": 1,
"house_id": "0363200000499764",
"address": "Bos en Lommerplein 104, Amsterdam",
"street": "Bos en Lommerplein"
"house_id": "0363200000499764",
"city": "Amsterdam",
"price": 700000
"date_searched": "2022-10-08 14:00:00",
"rating": 2
}
]
The Houses tables is an exact copy of a table from an existing database and will be updated outside of Django (hence managed = False). The house_id field of the House model is the primary key, but not an integer field, rather a characterfield with some leading 0's in the id.
Since I specify it as a foreign key, it automatically adds the suffix _id in the column name in the database (this is how I would like to have it, with an identical name as the house_id column in the Houses table).
There are millions of houses in my table, and there will be thousands of searches for these houses in the future. Therefore, I would like to have my set-up "futureproof", so my questions are:
- How can I create a join in Django between the
House&Searchmodel to get a set of searches with all house information (e.g. address, price) for the respective houses in that search, filtered byUser? - What is the most efficient way to query the data in the database and expose it with Django REST api? I have read something online that you don't want to put too much 'business logic' in either your serializer or views. Where do I make the join between the tables (and filter the data per user) then in my case?
Two questions in one, but I am in desperate need for help as I am a bit clueless at the moment. Thanks!