django form is returning None even if something is in the input

Multi tool use
Multi tool use
The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


django form is returning None even if something is in the input



Hello so I've been creating a custom form int django and everything has been working the way I thought it would until i came across this problem. So I've created a form for instructions:


class InstructionForm(forms.Form):
step = forms.IntegerField(widget=forms.HiddenInput(attrs={'value':1}))
instruction = forms.CharField(widget=forms.Textarea)



Which I created a Formset for so I can let the user add as many as they want.



view.py


def create(request):
recipeForm = RecipeForm()
ingredientFormSet = formset_factory(IngredientForm, extra=4)
instructionFormSet = formset_factory(InstructionForm)

if request.method == "POST":
recipe = RecipeForm(request.POST)
ingredients_forms = ingredientFormSet(request.POST, prefix="ingredient")
instruction_forms = instructionFormSet(request.POST, prefix="instruction")

if recipe.is_valid() and ingredients_forms.is_valid() and instruction_forms.is_valid():
newRecipe = Recipe()
newRecipe.title = recipe.cleaned_data['title']
newRecipe.description = recipe.cleaned_data['description']
newRecipe.save()

for ingredient in ingredients_forms:
cd = ingredient.cleaned_data
ingredientName = cd.get('ingredient')
try:
ingredientObj = Ingredient.objects.get(name=str(ingredientName))
except Ingredient.DoesNotExist:
ingredientObj = Ingredient(name=str(ingredientName))
finally:
ingAmount = IngredientAmount()
ingAmount.amount = cd.get('amount')
ingAmount.unit = cd.get('unit')

ingredientObj.save()

ingAmount.ingredient = ingredientObj
ingAmount.recipe = newRecipe
ingAmount.save()
newRecipe.ingredients.add(ingredientObj)
newRecipe.save()
#used a counter because my initial way of doing this wont work
i=1
for instruction in instruction_forms:
cd = instruction.cleaned_data
instruct = cd.get('instruction')
# I feel like the problem is somewhere in here
instructObj = Instruction(instruction=instruct)
instructObj.step = i
instructObj.recipe = newRecipe
instructObj.save()
i+=1
else:
ingredients_forms = ingredientFormSet(prefix="ingredient")
instruction_forms = instructionFormSet(prefix="instruction")

return render(request, 'foods/createFood.html',{'recipeForm':recipeForm, 'ingredientFormSet': ingredients_forms, 'instructionFormSet': instruction_forms})



so the ingredients form and the recipe form work just fine I can add Ingredients and they'll all be added to the database. But if I add an instruction the first one works all the others won't they return None.



createFood.html


<div class="container" id="foodsPage">

<form method="POST">
{% csrf_token %}
{{recipeForm.as_p}}

{{ingredientFormSet.management_form}}
{% for ingredient in ingredientFormSet %}
<div class="fieldWrapper" id="ingForm0">
{{ingredient.amount.label_tag}}
{{ingredient.amount}}
{{ingredient.unit.label_tag}}
{{ingredient.unit}}
{{ingredient.ingredient.label_tag}}
{{ingredient.ingredient}}
</div>
{% endfor %}
<div id="addMoreIng">
</div>
<input type="button" id="addIngredient" onclick="addIngFunction()" value="Add Ingredient">
</div>


<div class="instructions">
<div id="addMoreIns">
{{instructionFormSet.management_form}}
{% for instruction in instructionFormSet %}
{{instruction.step}}
{{instruction.instruction.label_tag}}
{{instruction.instruction}}
</div>
</div>
{% endfor %}





<input type="button" id="addInstruction" onclick="addInsFunction()" value="Add instruction">

<script>

function addIngFunction(){
$('#id_ingredient-TOTAL_FORMS').val(function(i, oldval){
oldval
var html = '<div class="fieldWrapper" id="ingForm'+oldval+'">'+
'<label for="id_ingredient-'+oldval+'-amount">Amount:</label>'+
' <input type="number" name="ingredient-'+oldval+'-amount" step="any" id="id_ingredient-'+oldval+'-amount" />'+
' <label for="id_ingredient-'+oldval+'-unit">Unit:</label>'+
' <input type="text" name="ingredient-'+oldval+'-unit" maxlength="3" id="id_form-'+oldval+'-unit" />'+
' <label for="id_ingredient-'+oldval+'-ingredient">Ingredient:</label>'+
' <input type="text" name="ingredient-'+oldval+'-ingredient" maxlength="100" id="id_ingredient-'+oldval+'-ingredient" />'+
'</div>'


$('#addMoreIng').append(html)
return ++oldval;
})
}

function addInsFunction(){
$('#id_instruction-TOTAL_FORMS').val(function(i, oldval){

var val = parseInt(oldval)+1
var html = '<input type="hidden" name="instruction-'+oldval+'-step" value="'+val+'" id="id_instruction-'+oldval+'-step" />'+
'<label for="id_instruction-'+oldval+'-instruction">Instruction:</label>'+
'<textarea name="instruction-'+oldval+'-instruction" cols="40" rows="10" id="id_instruction-'+oldval+'-instruction">'+
'</textarea>'

$('#addMoreIns').append(html)
return ++oldval;
})
}
</script>


<input type="submit" value="submit recipe">


</form>

</div>



I can't figure out why any of the added instructions return None.
can anyone help me out?




1 Answer
1



You are closing two divs inside the {% for instruction in instructionFormSet %}
but they should be closed outside the loop. I haven't checked it, but this may close more tags when parsed by the browser into the DOM than intended including implicitly the form tag.


div


{% for instruction in instructionFormSet %}


form



This could lead to some inputs not being inside the form anymore (according to browser DOM) and therefore not being submitted by the browser in the POST request. Try fixing your HTML.





Thank you so much, I feel stupid that the only problem was the html
– Aaron McCommon
yesterday






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

fvCip4 01EUEbgLkxAbxYELD 2n
uE1JJNkrKSs Yf3ehw,QdCJ,qF9Q7sSj maHlKEbX,W8BBPJh6vu89 Q5rv,q s1i

Popular posts from this blog

Keycloak server returning user_not_found error when user is already imported with LDAP

PHP parse/syntax errors; and how to solve them?

415 Unsupported Media Type while sending json file over REST Template