Нужны советы по структуре полей «многие ко многим» в Джанго - PullRequest
0 голосов
/ 06 октября 2018

Я создаю REST-API, который будет использоваться приложением Angular - это для сайта моей гитарной компании.Существует страница профиля исполнителя, на которой отображается имя исполнителя, краткая биография и список проектов (групп), с которыми они связаны, и диапазоны дат, с которыми они были активны.Здесь все становится сложнее.

Любой данный проект может быть связан с более чем одним артистом - то есть у меня может быть два гитариста из одной группы.Я смог решить эту ассоциацию, создав поле «многие ко многим», и оно прекрасно работало… пока я не понял, что у меня есть артисты, которые были в одной группе в разное время.

Я пробовал много подходовдо сих пор.Хотел бы я перечислить их, но я вроде как потерял след.Но код ниже - это то, где я сейчас нахожусь.Я действительно могу связать группу с несколькими артистами, но я не могу связать разные диапазоны дат для разных артистов в одних и тех же группах.Любое руководство высоко ценится.

class projectDate(models.Model):
    begin = models.DateField()
    end = models.DateField()


    def __str__(self):
        string_date_range = self.begin.strftime("%d/%m/%y") + "-" + self.end.strftime("%d/%m/%y")
        return  string_date_range

class artistProfiles(models.Model):
    artist_name = models.CharField(max_length=20)
    artist_image = models.URLField()
    description = models.TextField(max_length=500)
    band_website = models.URLField()

    def __str__(self):
        return self.artist_name


class artistProjects(models.Model):
    project_name = models.CharField(max_length=20)
    dates = models.ManyToManyField(projectDate, related_name='date_span')
    artists = models.ManyToManyField(artistProfiles, related_name='projects')

    def __str__(self):
        return self.project_name



class artistSocialMedia(models.Model):
    facebook = models.URLField()
    twitter = models.URLField()
    instagram = models.URLField()
    artist = models.ForeignKey(artistProfiles, related_name='social_media', on_delete=models.CASCADE)

    def __str__(self):
        return self.artist.artist_name

Ответы [ 3 ]

0 голосов
/ 06 октября 2018

Не уверен, смогу ли я решить ваши проблемы или нет.Я собираюсь описать это простым способом, чтобы вы могли просто настроить его с вашими моделями.Это мой совет.Надеюсь, что это решит ваши проблемы.

Artist Profile
id (PK)
artist_name
artist_image
description
band_website

Artist Social Media
id (PK)
artist_profile_id (FK)(Artist Profile)
facebook
twitter
instagram

Artist Project
id (PK)
artist_band_project_id (FK)(Artis Band Project) 

Artist Band Project
id (PK)
begin
end

Artist Band Project Member
id (PK)
artis_band_project_id (FK)(Artist Band Project)
artis_profile_id (FK)(Artist Profile)

С уважением,

Meikelwis Wijaya

0 голосов
/ 09 октября 2018

@ blhsing Закончилось тем, что был самым близким из всех ответов, но потребовалось немного больше массажа, чтобы получить отношения и структуру JSON, которые я искал.

Вот что сработало для моделей: из django.db import models

class artistProfile(models.Model):
    artist_name = models.CharField(max_length=20)
    artist_image = models.URLField()
    description = models.TextField(max_length=500)
    band_website = models.URLField()

    def __str__(self):
        return self.artist_name

class artistProject(models.Model):
    project_name = models.CharField(max_length=20)


    def __str__(self):
        return self.project_name


class projectTenure(models.Model):
    begin = models.DateField()
    # blank and null are allowed here in case an artists is still with a given project
    end = models.DateField(blank=True, null=True)

    project = models.ForeignKey(artistProject, on_delete=models.CASCADE)
    artist = models.ForeignKey(artistProfile, on_delete=models.CASCADE,
                               related_name='projects')

    def __str__(self):
        #   TODO: find a way to return the related project and artist names
        string_date_range = self.begin.strftime("%d/%m/%y") + "-"
        return string_date_range


class artistSocialMedia(models.Model):
    facebook = models.URLField()
    twitter = models.URLField()
    instagram = models.URLField()
    artist = models.ForeignKey(artistProfile, related_name='social_media',
                               on_delete=models.CASCADE)

    def __str__(self):
        return self.artist.artist_name

А вот как я его сериализовал:

from rest_framework import serializers
from .models import (artistProfile, artistProject, projectTenure, artistSocialMedia)


class artistSocialMediaSerializer(serializers.ModelSerializer):
    class Meta:
        model = artistSocialMedia
        fields = ('facebook', 'twitter', 'instagram')


class artistProjectSerializer(serializers.ModelSerializer):
    class Meta:
        model = artistProject
        fields = ('project_name',)


class projectTenureSerializer(serializers.ModelSerializer):
    project_name = serializers.CharField(source='project.project_name')

    class Meta:
        model = projectTenure
        fields = ('project_name', 'begin', 'end')


class artistProfileSerializer(serializers.ModelSerializer):
    projects = projectTenureSerializer(many=True, read_only=True)
    social_media = artistSocialMediaSerializer(many=True, read_only=True)

    class Meta:
        model = artistProfile
        fields = ('artist_name', 'artist_image', 'description',
                  'band_website', 'projects', 'social_media')
0 голосов
/ 06 октября 2018

artistProjects и projectDate не должны быть отношением многие-ко-многим, поскольку projectDate относится к проекту и вряд ли будет использоваться многими.Вместо этого вы можете сделать artistProjects внешним ключом в projectDate, чтобы у artistProjects могло быть много projectDate с, но не наоборот:

class projectDate(models.Model):
    begin = models.DateField()
    end = models.DateField()
    project = models.ForeignKey(artistProjects, related_name='dates')

Обратите внимание, что artistProjects представляет только одинпроект, поэтому вы должны избегать давать ему имя во множественном числе.Присвоение ему имени artistProject сделает ваш код более читабельным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...