在Django中将模型用作另一个模型的多个字段

时间:2019-04-19 10:22:11

标签: django model

我正在创建一些音乐应用。我有“曲目”模型,我想让用户创建可以包含多个曲目的播放列表。我的搜索无济于事。 (也可以在多个播放列表中使用一个曲目,例如,可以在播放列表“ YYY”和播放列表“ ZZZ”中使用曲目“ XXX”。)

这是models.py:

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

#Model that accutaly contains user's tracks/songs
class Track(models.Model):
    title = models.CharField(max_length=40, null=True)
    description = models.CharField(max_length=500, null=True)
    author = models.ForeignKey(User, default=None, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    miniature = models.ImageField(upload_to='images/track', default="defaults/default.png", validators=[validate_miniature_file_extension])

    audio_or_video = models.FileField(upload_to='audio_and_video/', default="file_not_found", validators=[validate_track_file_extension])

#Model that contains playlists
class Playlist(models.Model):
    title = models.CharField(max_length=40, null=True)
    description = models.CharField(max_length=500, null=True)
    author = models.ForeignKey(User, default=None, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    miniature = models.ImageField(upload_to='images/playlist', default="defaults/default.png", validators=[validate_miniature_file_extension])

    Tracks = models.ForeignKey(Track, default=None, on_delete=models.CASCADE) # I tried this, but it won't work at all because it can contain only one Track

1 个答案:

答案 0 :(得分:2)

1 / 在“播放列表”类中,属性应为小写tracks而不是Tracks

2 / 因为曲目可以与许多播放列表相关,而播放列表可以与许多曲目相关,所以您需要ManyToManyField (而不是ForeignKey):

tracks = models.ManyToManyField(Track)

3 / 然后,您可以添加任意数量的曲目

playlist.tracks.add(tracks1)
playlist.tracks.add(tracks2)
...

在添加带有.save()的曲目时无需使用.add()方法

参考:

外键: https://docs.djangoproject.com/fr/2.1/ref/models/fields/#foreignkey

多对多: https://docs.djangoproject.com/fr/2.1/ref/models/fields/#manytomanyfield