Несколько типов пользователей и рейтинги в Джанго - PullRequest
0 голосов
/ 12 марта 2019

Я делаю бэкэнд DRF с тремя типами пользователей: клиент, личный тренер и владелец спортзала. Я хочу, чтобы все поля в классе CustomUser применялись к каждому типу пользователя. Мне также нужны некоторые специфические атрибуты для каждого типа пользователя (например, фотография только для личного тренера и владельца спортзала). Это правильный способ сделать это?

# models.py

class CustomUser(AbstractUser):
    USER_TYPE_CHOICES = (
        ('customer'),
        ('personal_trainer'),
        ('gym_owner'),
    )

    user_type = models.CharField(blank=False, choices=USER_TYPE_CHOICES)
    name = models.CharField(blank=False, max_length=255)
    country = models.CharField(blank=False, max_length=255)
    city = models.CharField(blank=False, max_length=255)
    phone = models.CharField(blank=True, max_length=255)
    ratings = models.ForeignKey(Rating, on_delete=models.CASCADE, null=True)
    created_at = models.DateField(auto_now_add=True)

    def __str__(self):
        return self.name


class Customer(models.Model):
    user = models.OneToOneField(
        CustomUser, on_delete=models.CASCADE, primary_key=True)


class PersonalTrainer(models.Model):
    user = models.OneToOneField(
        CustomUser, on_delete=models.CASCADE, primary_key=True)
    photo = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)


class GymOwner(models.Model):
    user = models.OneToOneField(
        CustomUser, on_delete=models.CASCADE, primary_key=True)
    photo = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)

У меня также есть модель оценок. Я хочу иметь возможность оставить рейтинг в качестве клиента для личного тренера или тренажерного зала. Каждый рейтинг будет иметь отношение один к одному с его владельцем и целью. Я не уверен, однако, как я могу сделать отношения ..?

# models.py

class Rating(models.Model):
    STAR_CONVERSION = (
        (1, 'One Star'),
        (2, 'Two Stars'),
        (3, 'Three Stars'),
        (4, 'Four Stars'),
        (5, 'Five Stars'),
    )

    rating = models.PositiveSmallIntegerField(choices=STAR_CONVERSION)
    caption = models.TextField(blank=True)

    owner = models.OneToOneField(Customer, on_delete=models.CASCADE)

    # I want a target as a one to one relation to either PersonalTrainer or GymOwner
    target = models.OneToOneField(*either personal trainer or gym owner*)

1 Ответ

1 голос
/ 12 марта 2019

Вам нужно сделать owner и target ForeignKey вместо OneToOneField. С последним у вас может быть только один рейтинг для каждого клиента и один для каждого поставщика, что будет немного ограничительным:).

Для PersonalTrainer и GymOwner требуется наследование модели. Родительская модель будет либо абстрактным классом (с данными, сохраненными в таблицах отдельных дочерних моделей), либо (предпочтительно в этом случае, поскольку поля обеих моделей совпадают), данные будут сохранены в родительской модели ( например, Provider), в то время как дочерние модели будут прокси-моделями , основанными на данных родительской модели, но при необходимости обеспечивающими другое поведение.

Документы Django могут многое рассказать о различных вариантах наследования.

class Provider(models.Model):
    user = models.OneToOneField(
        CustomUser, on_delete=models.CASCADE, primary_key=True)
    photo = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)

class PersonalTrainer(Provider):
    class Meta:
        proxy = True

class GymOwner(Provider):
    class Meta:
        proxy = True

class Rating(models.Model):   
    # ...
    owner = models.ForeignKey(Customer, on_delete=models.CASCADE)
    target = models.ForeignKey(Provider, on_delete=models.CASCADE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...