具有反向外键的模型

Kir*_*n S 5 django

我正在尝试为音乐家模型创建一个 ModelForm,从中必须可以为每个音乐家选择多个专辑。由于专辑是反向外键,我认为 ModelForm 不会将专辑值保存到数据库中。是否有任何可能的方法让这个工作

请帮助我并提前致谢

这是我的模型:

class musicianForm(forms.ModelForm):


   album=forms.ModelMultipleChoiceField(queryset=Musician.objects.all(),
                                           widget=forms.widgets.CheckboxSelectMultiple())


   class Meta:
       model = Musician
       fields = ('album','first_name','last_name','instrument')
Run Code Online (Sandbox Code Playgroud)

模型.py

from django.db import models

class Musician(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    instrument = models.CharField(max_length=100)

class Album(models.Model):
    artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)

管理员.py

class musicianAdmin(admin.ModelAdmin):
    form = musicianForm
Run Code Online (Sandbox Code Playgroud)

1GD*_*DST 0

最好的方法是__init__像这样覆盖表单的:

class MusicianForm(forms.ModelForm):

    musician = forms.CharField()

    def __init__(self, *args, **kwargs):
        super(MusicianForm, self).__init__(*args, **kwargs)
        self.fields['musician'] = forms.MultipleChoiceField(         
            widget=forms.CheckboxSelectMultiple, 
            choices=(((choice.id), choice) for choice in Musician.objects.all())
            )

    class Meta:
        model = Album
        fields = ('name','release_date','num_stars')
Run Code Online (Sandbox Code Playgroud)

然后,models.py您将必须在您的模型中创建另一个模型来将艺术家连接到专辑。如果您不这样做,则只能将一位艺术家添加到专辑中(可能存在合作,因此我们必须这样做):

class Musician(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    instrument = models.CharField(max_length=100)

    def __str__(self):
        return self.first_name + " " + self.last_name

class Album(models.Model):
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()
    
    def __str__(self):
        return self.name

class AlMu(models.Model):
    artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
    album = models.ForeignKey(Album, on_delete=models.CASCADE)
Run Code Online (Sandbox Code Playgroud)

然后要处理我们的数据并连接所有内容,请执行以下操作:

def create_album(request):
    if request.method == "POST":
        form = MusicianForm(request.POST)
        if form.is_valid():
            mu = form.save(commit=False)
            mu.name =  form.cleaned_data['name']
            mu.release_date = form.cleaned_data['release_date']
            mu.num_stars = form.cleaned_data['num_stars']
            mu.save()
            for i in form.cleaned_data['musician']:
                mus = Musician.objects.get(id=i)
                AlMu(artist=mus, album=mu).save()
            # do something fancy here. Redirect or so
    else:
        form = MusicianForm()

    return render(request, 'create_album.html', {'form': form})
Run Code Online (Sandbox Code Playgroud)

您的create_album.html文件将如下所示(没什么特别的):

<form method="POST">
    {{form}}
    <input type="Submit" value="Submit">
</form>
Run Code Online (Sandbox Code Playgroud)