开发者

Validation fails on a select box whose contents are added by an Ajax call

开发者 https://www.devze.com 2023-01-10 03:46 出处:网络
This question is related to this one Remove all the elements in a foreign key select field I had a foreign key field in my model which was getting pre-populated by its data and I wanted the select l

This question is related to this one

Remove all the elements in a foreign key select field

I had a foreign key field in my model which was getting pre-populated by its data and I wanted the select list to be empty. I did achieve that but the validation fails when I submit the form.

The error says "Select a valid choi开发者_如何学运维ce option. 1 is not one of the available choices).

These are my models

class RecipeIngredient(models.Model):
    recipe = models.ForeignKey(Recipe)
    ingredient = models.ForeignKey(Ingredient)
    serving_size = models.ForeignKey(ServingSize)
    quantity = models.IntegerField()
    order = models.IntegerField()
    created = models.DateTimeField(auto_now_add = True)
    updated = models.DateTimeField(auto_now = True)

class RecipeIngredientForm(forms.ModelForm):
    serving_size = forms.ChoiceField(widget=forms.Select())

    class Meta:
        serving_size  = forms.ChoiceField(widget=forms.Select())
        model = RecipeIngredient
        fields = ('ingredient', 'quantity', 'serving_size')
        widgets  = {
            'ingredient': forms.TextInput(attrs={'class' : 'recipe_ingredient'}),
            'quantity': forms.TextInput(),
            'serving_size' : forms.Select(attrs={'class' : 'ddl'}),
        }

I get an error on the third line

recipeIngredients = models.RecipeIngredientFormSet(request.POST)
print(recipeIngredients.errors)
objRecipeIngredients = recipeIngredients.save(commit=False)

I want the select box to be empty because it gets populated by an ajax call. Any ideas what to do so the model passes the validation?

EDIT

Serving Size Model

class ServingSize(models.Model):
    name = models.CharField(max_length = 255)
    unit = models.CharField(max_length = 125)
    food_group = models.ForeignKey(FoodGroup)
    created = models.DateTimeField(auto_now_add = True)
    updated = models.DateTimeField(auto_now = True)

    objects = models.Manager()
    dal_objects = ServingSizeManager()

    def __unicode__(self):
        return self.name;


First, why do you have serving_size in the Meta class?

I would use an extra field in the ModelForm and leave out serving_size field altogether.

class RecipeIngredientForm(forms.ModelForm):
    mycustomfield = forms.ChoiceField(widget=forms.Select())

    class Meta:
        model = RecipeIngredient
        exclude = ('serving_size', 'created', 'updated') #etc

Then in the view I would manipulate the form to assign a valid ServingSize to the serving_size field.

[EDIT]

Alright, your actual implementation will depend on what you are pulling through ajax and how. But see the following code: -

Your form: -

class CustomRecipeIngredientForm(forms.ModelForm):
    recipe = forms.ModelChoiceField(            Recipe.objects.all(),
                                                widget=forms.Select(attrs={'class':'customclass',}))

    ingredient = forms.ModelChoiceField(        Ingredient.objects.all(),
                                                widget=forms.Select(attrs={'class':'recipe_ingredient',}))

    my_custom_serving_size_field = forms.ChoiceField(widget=forms.Select(attrs={'class':'ddl',}))

    quantity = forms.IntegerField()

    order = forms.IntegerField()

    class Meta:
        model = RecipeIngredient
        exclude = ('serving_size', 'created', 'updated',)

Pull your data through ajax into the my_custom_serving_size_field

Your view: -

def my_view(request):
    if request.method == 'POST':
        form = CustomRecipeIngredientForm(data=request.POST)
        if form.is_valid():
            new_recipe_ingredient = form.save(commit=False)
            new_recipe_ingredient.serving_size = ServingSize.objects.get(pk=form.cleaned_data['my_custom_serving_size_field'])
            new_recipe_ingredient.save()             

            return HttpResponseRedirect(reverse('redirect_to_wherever'))
    else:
        form = CustomRecipeIngredientForm()
    return render_to_response('path/to/my_template.html', {'form': form}, context_instance=RequestContext(request))

Of course, your ServingSize.objects.get() logic will depend on what your are pulling through ajax and how. Try something along these lines and let us know.


Looks like you want a ModelChoiceField, which

Allows the selection of a single model object, suitable for representing a foreign key

0

精彩评论

暂无评论...
验证码 换一张
取 消