问题
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