django 具有反向外键的模型窗体

wqsoz72f  于 2023-02-14  发布在  Go
关注(0)|答案(1)|浏览(124)

我正在尝试为音乐家创建一个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')

models.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()

admin.py

class musicianAdmin(admin.ModelAdmin):
    form = musicianForm
aoyhnmkz

aoyhnmkz1#

最好的方法是覆盖窗体的__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')

然后在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)

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

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

您的create_album.html文件将如下所示(没有什么花哨的):

<form method="POST">
    {{form}}
    <input type="Submit" value="Submit">
</form>

相关问题