问题
I am trying to create a pretty complicated form and break it up using formwizard. The first thing I am trying to do is get the ManyToManyField using through to display, Then I need to figure out how to make it all save.
#models.py
----------------------
class Meat(models.Model):
name = models.charField(max_length=200)
company = models.CharField(max_length = 200)
class Starch(models.Model):
name = models.CharField(max_length=200)
company = models.CharField(max_length=200)
class Recipe(models.Model):
name = models.CharField(max_length=200)
description = models.TextField(help_text='Please describe the finished dish')
meat = models.ManyToManyField('Meat' through='RecipeMeat')
meat_notes = models.TextField()
starch = models.ManyToManyField('Starch' through='RecipeStarch')
starch_notes = models.TextField()
class RecipeMeat(models.Model):
recipe = models.ForeignKey(Recipe)
meat = models.ForeignKey(Meat)
qty = models.FloatField()
class RecipeStarch
recipe = models.ForeignKey(Recipe)
starch = models.ForeignKey(Starch)
qty = models.FloatField()
.
#forms.py
-------------------
class RecipeForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ('name', 'description')
class RecipeMeatForm(forms.ModelForm):
class Meta:
model = RecipeMeat
class RecipeMeatNotesForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ('meat_notes',)
class RecipeStarch(forms.ModelForm):
class Meta:
model = RecipeStarch
class RecipeStarchNotesForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ('starch_notes')
MeatFormSet = inlineformset_factory(Recipe, RecipeMeat, form=RecipeMeatForm, extra=1)
.
#views.py
---------------------------
class CreateRecipeWizard(SessionWizardView):
template_name = "create-recipe.html"
instance = None
file_storage = FileSystemStorage(location= 'images')
def dispatch(self, request, *args, **kwargs):
self.instance = Recipe()
return super(CreateRecipeWizard, self).dispatch(request, *args, **kwargs)
def get_form_instance( self, step ):
return self.instance
def done( self, form_list, **kwargs ):
self.instance.save()
return HttpResponseRedirect(reverse(all-recipes))
.
#urls.py
------------------------------
url(r'^create-recipe/$', views.CreateRecipeWizard.as_view([RecipeForm, MeatFormSet, RecipeMeatNotesForm, RecipeStarchNotesForm]), name='create-recipe'),
.
I am a bit of a rookie with this django stuff. The Recipe part is much longer and more complicated but pretty much the same pattern. If any one could help point me in the right on how to get my ManyToManyField using through part figured out or pointed in the right direction it would be greatly appreciated.
回答1:
To save the ManyToMany relationship on a formwizard process you can do something like this;
def done(self, form_list, **kwargs):
form_data_dict = self.get_all_cleaned_data()
m2mfield = form_data_dict.pop('m2mfield')
instance = form_list[0].save()
for something in m2mfield:
instance.m2mfield.add(something)
return render_to_response(
'done.html', {},
context_instance=RequestContext(self.request)
)
In this example the first form in the list is a ModelForm
for the thing I'm trying to create and it has a ManyToManyField
to another model for which I have a form second in the process. So I grab that first form & save it, then grab the field from the cleaned data from the second form and save the selected options to the M2M field.
来源:https://stackoverflow.com/questions/21152731/django-manytomany-field-using-through-and-formwizard