Как (оптимально) сериализовать объединенные таблицы в django rest framework, с отношением "многие-к-одному" с нецелым первичным ключом
У меня есть база данных PostgreSQl с тремя основными таблицами: houses
, searches
для этих домов и users
, в которых производится поиск.
Дома имеют характеристики, например, адрес и цену, пользователь может несколько раз искать один и тот же дом и в процессе поиска давать дому оценку.
Дом:
[
{
"house_id": "0363200000499764",
"address": "Bos en Lommerplein 104, Amsterdam",
"street": "Bos en Lommerplein"
"city": "Amsterdam",
"price": 700000
},
]
Множественные поиски одного и того же дома разными пользователями:
[
{
"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
},
]
Пользователи:
[
{
"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"
},
]
Я использую Django и создал модели для этих таблиц в базе данных.
Отрывок из моего models.py
файла:
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'
Теперь я использую фреймворк Django REST для сериализации данных из базы данных в json-поля.
Например, я создал HouseSerializer
, который сериализует данные о доме в json.
Фрагмент моего 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")
Теперь я хотел бы раскрыть все поиски по каждому пользователю и показать всю информацию о доме, включая рейтинг, который они присвоили дому.
Итак, для пользователя 1 ответ в формате json должен быть следующим:
[
{
"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
}
]
таблицы Houses является точной копией таблицы из существующей базы данных и будет обновляться вне Django (отсюда managed = False
). Поле house_id
модели House
является первичным ключом, но не целочисленным, а символьным полем с несколькими ведущими 0 в id.
Поскольку я указываю его как внешний ключ, он автоматически добавляет суффикс _id
в имя столбца в базе данных (именно так я хотел бы его иметь, с идентичным именем, как столбец house_id
в таблице Houses).
В моей таблице миллионы домов, и в будущем будут тысячи поисков этих домов. Поэтому я хотел бы, чтобы моя установка была "устойчива к будущему", поэтому мои вопросы следующие:
- Как я могу создать соединение в Django между моделью
House
&Search
для получения набора поисковых запросов со всей информацией о домах (например, адрес, цена) для соответствующих домов в этом поиске, отфильтрованных поUser
? - Какой наиболее эффективный способ запросить данные в базе данных и представить их с помощью Django REST api? Я читал в интернете, что не стоит помещать слишком много "бизнес-логики" ни в сериализатор, ни в представления. Где мне сделать соединение между таблицами (и фильтровать данные по пользователям) в моем случае?
Два вопроса в одном, но я отчаянно нуждаюсь в помощи, так как в данный момент я немного не понимаю. Спасибо!