Modelform with reverse foriegnkey

∥☆過路亽.° 提交于 2021-02-16 14:41:10

问题


I am trying to create a ModelForm for musician Model from which it must be possible to select a number of albums for each musician.Since album is reverse foreignkey i think ModelForm doesn't saves album values to the database.Is there any possible methods to get this working

please help me and thanks in advance

here is my 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

回答1:


The best way to do this is to overwrite the __init__ of your form like this:

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

Then in your models.py you will have to create another model to connect the artists to the albums. If you don't do this, you can only add one artist to an album (there might be collaborations, so we have to do this):

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)

Then to process our data and connect everything, do this:

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

Your create_album.html file will look like this (nothing fancy):

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


来源:https://stackoverflow.com/questions/39708397/modelform-with-reverse-foriegnkey

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!