Can anyone help me why my formset is showing invalid when trying to update the form. It works perfectly when creating the form. The normal form is editing but the formset is not.
`def content_edit_view(request, id):
course = get_object_or_404(Course, id=id)
LectureFormset = modelformset_factory(Lecture, fields=('lecture_title', 'lecture_content', 'youtube_url'), extra=0)
if course.user != request.user:
raise Http404()
if request.method == 'POST':
content_edit_form = ContentEditForm(request.POST or None, request.FILES or None, instance=course)
formset = LectureFormset(request.POST or None, request.FILES or None)
if content_edit_form.is_valid():
content_edit_form.save()
data = Lecture.objects.filter(course=course)
# give index of the item for a formset item strting form 0 and (f)the item itself
if formset.is_valid():
for index, f in enumerate(formset):
if f.cleaned_data:
if f.cleaned_data['id'] is None:
video = Lecture(course=course, lecture_title=f.cleaned_data.get('lecture_title'), lecture_content=f.cleaned_data.get('lecture_content'), youtube_url=f.cleaned_data.get('youtube_url'))
video.save()
else:
video = Lecture(course=course, lecture_title=f.cleaned_data.get('lecture_title'), lecture_content=f.cleaned_data.get('lecture_content'), youtube_url=f.cleaned_data.get('youtube_url'))
d = Lecture.objects.get(id=data[index].id) #get slide id which was uploaded
d.lecture_title = video.lecture_title # changing the database tiitle with new title
d.lecture_content = video.lecture_content #changing the database content with new content
d.youtube_url = video.youtube_url # changing the database content with new content
d.save()
return redirect('teacher-profile')
else:
print('formset is invalid')
else:
print("form is invalid")
else:
content_edit_form = ContentEditForm(instance=course)
formset = LectureFormset(queryset=Lecture.objects.filter(course=course))
context = {
'contentForm': content_edit_form,
'course': course,
'formset': formset,
}
return render(request, 'apps/contentEdit.html', context)`
Related
I have the following view code
def edit_pal(request,pal_id):
pals=palabout.objects.get(id=pal_id)
form2=editpalForm(request.POST or None,instance=pals)
RecipeIngredientFormset = modelformset_factory(palabout, form=editspalForm,extra=0)
formset = RecipeIngredientFormset(request.POST or None,prefix=pals)
context={
"formset": formset,
"form2":form2,
"pals":pals
}
if request.method == 'POST':
if form2.is_valid() and formset.is_valid():
parent = form2.save(commit=False)
parent.save()
for form in formset:
child = form.save(commit=False)
child.recipe = parent
child.save()
context['message']='Data Saved'
return redirect('hod:manage_pal')
return render(request,"edit-pal.html",context)
I remove formset.is_validso it's working but it's not working when i added more for used formset.is_validso why isn't saving file or details show? Can anyone help this?
I think you need to only redirect if the forms are valid so try this view:
from django.shortcuts import get_object_or_404
def edit_pal(request,pal_id):
pals=get_object_or_404(palabout,id=pal_id)
if request.method == 'POST':
form2=editpalForm(request.POST,instance=pals)
RecipeIngredientFormset = modelformset_factory(palabout, form=editspalForm,extra=0)
formset = RecipeIngredientFormset(request.POST,prefix=pals)
if form2.is_valid() and formset.is_valid():
parent = form2.save(commit=False)
parent.save()
for form in formset:
child = form.save(commit=False)
child.recipe = parent
child.save()
context['message']='Data Saved'
return redirect('hod:manage_pal')
else: # if the form is not valid
return redirect("hod:some_error_page")
else: # GET request
RecipeIngredientFormset = modelformset_factory(palabout, form=editspalForm,extra=0)
formset = RecipeIngredientFormset(prefix=pals)
context={
"formset": formset,
"form2":editpalForm(instance=pals),
"pals":pals
}
return render(request,"edit-pal.html",context)
I try to write testcase for one of my view that use a form.
views.py
def parametrage(request,pk):
parametrage = get_object_or_404(Parametrage, asp_par_cle = pk)
form = ParametrageForm(request, data=request.POST or None, instance = parametrage)
print('form.data',form.data)
if form.is_valid():
parametrage = form.save()
parametrage.opr_nom = request.user.username
parametrage.opr_dat = timezone.now()
form.save()
return redirect('pharmacy:dashboard')
return render(request, 'pharmacy/parametrage.html', {'form': form})
tests.py
class PharmacyParametrageTestCase(TestCase):
def setUp(self):
Parametrage.objects.create(asp_par_loc='TR',asp_par_ale=1,asp_par_con=8)
def test_email_alert(self):
instance = Parametrage.objects.get(asp_par_cle=1)
data = json.dumps({"asp_par_ale":2,})
response = self.client.post(reverse('pharmacy:parametrage', kwargs={'pk':1}),instance=instance, data=data, follow=True, content_type='application/json')
self.assertEqual(response.status_code,200)
self.assertEqual(Parametrage.objects.get(asp_par_cle=1).asp_par_ale,2)
The second assert failed because Parametrage instance is not updated.
form.is_valid() return False and form.errors do not return any error.
form.data is empty
obviously, I never change asp_par_ale value but don't know how to do that in tests.
I try to pass data but doesn't work neither
appreciate some help
i found i guess, when you said, object is not updated, you spoke only about opr_dat and opr_dat ? You called form.save() twice. You have to call isntance save function :
def parametrage(request,pk):
parametrage = get_object_or_404(Parametrage, asp_par_cle = pk)
form = ParametrageForm(request, data=request.POST or None, instance = parametrage)
print('form.data',form.data)
if form.is_valid():
parametrage = form.save(commit=False)
parametrage.opr_nom = request.user.username
parametrage.opr_dat = timezone.now()
parametrage.save()
return redirect('pharmacy:dashboard')
return render(request, 'pharmacy/parametrage.html', {'form': form})
[RESOLVED] I FOUND THE SOLUTION AND UPDATED WITH THE WORKING CODE BELOW
I'm trying to submit two forms with one button.
I check a few other posts in here, but I'm not sure if the code below is the correct.
def cars_detail(request, car_id):
car = Car.objects.get(id=car_id)
profile_form = ProfileForm()
booking_form = BookingForm()
return render(request, 'cars/detail.html', { 'car': car, 'booking_form': booking_form, 'profile_form': profile_form })
def addbooking(request, car_id):
if request.method == 'POST':
profile_form = ProfileForm(request.POST)
booking_form = BookingForm(request.POST)
print(request.POST)
if profile_form.is_valid() or booking_form.is_valid():
# do stuff here
# form = ProfileForm(request.POST)
new_profile = profile_form.save(commit=False)
new_profile.car_id = car_id
new_profile.user_id = request.user.id
new_profile.save()
# do stuff here
# form = BookingForm(request.POST)
new_booking = booking_form.save(commit=False)
new_booking.car_id = car_id
new_booking.user_id = request.user.id
new_booking.save()
return redirect('detail', car_id=car_id)
else:
profile_form = ProfileForm(prefix="profile_form")
booking_form = BookingForm(prefix="booking_form")
You have no code in the block after the “if”.
If there’s nothing to do in that instance negate the condition and remove the “else”
But do you want to reset both forms if only one of them is invalid? You might want this instead
if !profile_form.is_valid():
profile_form = Profile_form(prefix="profile_form")
if !booking_form.is_valid():
booking_form = Booking_form(prefix="booking_form")
I am trying to update a choice field before it is validated in Django. The reason for this is the choice field in question value is the Id of a model that i want to update.
def fuelLogSystemOne(request):
entries = FuelLogSystemOneMod.objects.all().order_by('date')
products = productsMod.objects.all()
if request.method == 'POST':
form = forms.AddFuelLogOneForm(request.POST, request.FILES)
productid = form['product'].value()
product = productsMod.objects.get(id=productid)
product_id = request.POST.get('product')
form.fields['product'].choices = [(product.product_type, product.product_type)]
if form.is_valid():
bucketsRemoved = form['buckets_added'].value()
product.stock -= bucketsRemoved
product.save(['stock'])
instance = form.save(commit=False)
instance.staff = request.user
instance.save()
return redirect('home')
else:
form = forms.AddFuelLogOneForm()
return render(request,'systems/fuellogsystemone.html',{'form':form,'entry':entries,'products':products})
The below part is where i am trying to change the form data before it gets validated so it doesn't say 'Select a valid choice. 1 is not one of the available choices'
product_id = request.POST.get('product')
form.fields['product'].choices = [(product.product_type, product.product_type)]
But when I first submit the form it is still saying 'Select a valid choice.'
At what point does Django validate the form because I am changing the form before the is_valid() method and it still hits this error?
This should be in your form, you have to override the init method, and pass the product id during form initialization in the views
forms.py
class AddFuelLogOneForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
product = kwargs.pop('product', None)
self.fields['product'].choices = [(product.product_type, product.product_type)]
views.py
def fuelLogSystemOne(request):
entries = FuelLogSystemOneMod.objects.all().order_by('date')
products = productsMod.objects.all()
if request.method == 'POST':
product_id = request.POST.get('product')
productid = form['product'].value()
product = productsMod.objects.get(id=productid)
product_id = request.POST.get('product')
form = forms.AddFuelLogOneForm(request.POST, request.FILES, product=product)
if form.is_valid():
bucketsRemoved = form['buckets_added'].value()
product.stock -= bucketsRemoved
product.save(['stock'])
instance = form.save(commit=False)
instance.staff = request.user
instance.save()
return redirect('home')
else:
form = forms.AddFuelLogOneForm()
return render(request,'systems/fuellogsystemone.html',{'form':form,'entry':entries,'products':products})
this my view code
if request.method == 'POST':
if 'cancel' in request.POST:
return redirect('incident.views.index')
if 'password' in request.POST:
registerform = UserRegisterForm(request.POST)
registerform = UserRegisterForm(request.POST)
createprofileform = UserCreateProfileForm(request.POST)
if registerform.is_valid() and createprofileform.is_valid():
result = registerform.save(commit=False)
result.set_password(request.POST['password'])
result.save()
member.user_id = user.id
member.member_id = result.id
member.save()
member_profile = UserProfile.objects.get(user=result.id)
createprofileform = UserCreateProfileForm(request.POST, instance=member_profile)
createprofileform.save()
is_member_screen = True
member_save_msg = 'New member has been added.'
return render(request, 'incident/about_me.html',
registerform':registerform,
'createprofile':createprofileform,
'member_save_msg': member_save_msg,
})
After every form submit,i want to clear the posted data,actually the form is holding the submitted data.I don't want to redirect the page to some other page as save success message will appear after every save.How to clear the posted data from form on every submit.
Thanks
Re-init the forms registerform and createprofileform to empty forms - no POST data, when you want to clear the data.
Sample:
if request.method == 'POST':
if 'cancel' in request.POST:
return redirect('incident.views.index')
if 'password' in request.POST:
registerform = UserRegisterForm(request.POST)
registerform = UserRegisterForm(request.POST)
createprofileform = UserCreateProfileForm(request.POST)
if registerform.is_valid() and createprofileform.is_valid():
# your code
...
#reset forms
registerform = UserRegisterForm()
createprofileform = UserCreateProfileForm()
return render(request, 'incident/about_me.html',
registerform':registerform,
'createprofile':createprofileform,
'member_save_msg': member_save_msg,
})