Django中多对多字段的结构需要的建议

时间:2018-10-06 02:07:01

标签: django python-3.x postgresql django-models

我正在构建REST-API,该应用程序将由Angular应用程序使用-这是我的吉他公司的网站。有一个“艺术家个人资料”页面,其中显示了艺术家的姓名,简短的个人简介以及与他们相关联的项目(乐队)的列表以及与他们一起活动的日期范围。这是事情变得复杂的地方。

任何给定的项目都可以与一个以上的艺术家相关联-即我可以有两个来自同一乐队的吉他手。我能够通过创建一个多对多的领域来解决这种联系,并且效果很好……直到我意识到我有在不同时间都属于同一乐队的艺术家。

到目前为止,我已经尝试了许多方法。我希望可以列出它们,但我有点迷路了。但是,下面的代码是我现在所在的位置。我确实可以将一个乐队与多个歌手联系在一起,但是不能将不同的日期范围与同一乐队中的不同歌手联系在一起。任何指导都将不胜感激。

++

3 个答案:

答案 0 :(得分:1)

artistProjectsprojectDate不应是多对多的关系,因为projectDate是特定于项目的,不太可能被许多人共享。您可以改为在artistProjects中将projectDate用作外键,这样artistProjects可以有多个projectDate,但反之则不能:

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

请注意,您的artistProjects仅代表一个项目,因此应避免使用复数名称。将其命名为artistProject将使您的代码更具可读性。

答案 1 :(得分:1)

不确定我是否可以解决您的问题。我将以简单的方式进行描述,以便您可以随模型进行调整。 这些是我的建议。希望它能解决您的问题。

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)

答案 2 :(得分:0)

@blhsing最终成为所有答案中最接近的一个,但是花了一些点按摩才能得到我想要的关系和JSON结构。

以下是适用于模型的内容: 从django.db导入模型

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')