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



我正在构建一个将被Angular应用程序使用的REST-API - 这是为我的吉他公司的网站准备的。有一个艺术家资料页面,显示艺术家的姓名,简短的个人简介和与他们关联的项目(乐队(列表以及他们活跃的日期范围。这就是事情变得复杂的地方。

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

到目前为止,我已经尝试了很多方法。我希望我能列出它们,但我有点迷失了方向。但是,下面的代码是我现在所处的位置。我确实可以将一个乐队与多个艺术家相关联,但我无法将不同的日期范围与同一乐队中的不同艺术家相关联。非常感谢任何指导。

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

artistProjectsprojectDate不应该是多对多关系,因为projectDate特定于项目,不太可能被许多人共享。您可以改为在projectDateartistProjects外键,以便artistProjects可以具有许多projectDate,反之则不然:

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

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

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

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)

问候

梅克尔维斯·维贾亚

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

最新更新