Настройка взаимоотношений между таблицами в Django

Пожалуйста, помогите правильно составить описание схемы базы данных в Django. Планирую создать 2 таблицы. Первая таблица - расширение стандартной таблицы User. Вопрос возник по второй таблице:

from django.db import models
from django.contrib.auth.models import User


class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name='Пользователь')
    full_name = models.CharField(max_length=50, verbose_name='Имя')
    avatar = models.FileField(upload_to='users_avatar', blank=True, null=True, help_text='Аватар пользователя')
    
class UserRating(models.Model):
    user = models.ForeignKey(User, null=True, on_delete=models.CASCADE, verbose_name='Пользователь')
    rating = models.CharField(max_length=1, verbose_name='Оценка')
    user_who_send_rating = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='Автор')
    name_user_who_send_rating = models.CharField(max_length=50, verbose_name='Имя автора')
    text_comment = models.TextField(verbose_name='Текст отзыва')
    date_send_rating = models.DateTimeField(auto_now_add=True, verbose_name='Создано')

Здесь будут храниться данные о рейтинге пользователя и отзывы о нем. Каждый пользователь может написать много отзывов другим пользователям. Ровно также он может получить много отзывов от других пользователей. Как во второй таблице лучше выставить взаимоотношения? Имя автора отзыва как-то можно заполнять автоматически из таблицы UserProfile ? У кого есть опыт в этом, дайте совет. Возможно тут стоит вообще поменять структуру ? Буду рад выслушать все мнения.


Ответы (1 шт):

Автор решения: Sergey S.

Пройдемся сначала по полям:

  • full_name в UserProfile: оно вам не нужно, так как в стандартной модели User объявлен метод get_full_name(), который возвращает нужное вам значение
  • name_user_who_send_rating в UserRating: аналогично
  • rating в UserRating: поменяйте тип поля на SmallPositiveIntegerField, так как в CharField можно ввести вместо числа, например, "+" или "?", или "а" - оно вам не надо; я не уверен как, но для SmallPositiveIntegerField можно указать аргументы min_value и max_value; как альтернативный вариант, вы можете оставить CharField, но жестко ограничить выбор рейтинга из списка с помощью аргумента choices; это будет выглядеть примерно так:
class UserRating(models.Model):
    RATTING_LIST = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
    ...
    rating = models.CharField(max_length=2, choices=RATING_LIST, verbose_name='Оценка')
    ...
  • user_who_send_rating в UserRating: измените models.CASCADE на models.SET_NULL и добавьте аргумент null=True – это поможет избежать ситуации, когда пользователь, удалив свой аккаунт, понизит рейтинг у остальных аккаунтов

А вот теперь про модели. Из модели UserProfile у вас остается только 1 поле - avatar (ну и ссылка на пользователя, естественно). Такой подход не очень рационален и вам придется каждый раз обращаться к 2 моделям. Почитайте материал, про изменение моделей пользователя. Но должен предупредить, что вам придется либо делать это с чистого проекта, либо удалять базу данных и миграции, так как такие изменения влияют на схему работы базы данных. Более подробную информацию вы можете найти в официальной документации

→ Ссылка