Updating Record with ModelForm - django

I am working on calling up a pre-populated form based on user input. I want to allow editing of the record in the resulting form, and then save the updates to the DB Record. Below is creating new records, not updating existing and I'm stuck on next steps.
def mod_customer(request):
params = json.loads(request.body)
selection = params['cst_id']
obj = AppCustomerCst.objects.get(id_cst=selection)
instance = get_object_or_404(AppCustomerCst, id_cst=selection)
form = CustomerMaintForm(request.POST or None, instance=instance)
if '_edit' in request.POST:
if form.is_valid():
form.save()
return redirect('customers')
elif form.is_valid() and '_delete' in request.POST:
# just for testing purposes. once mod is working, will update with delete
# AppCustomerCst.objects.filter(id_cst=selection).delete()
context = {'form': form}
return render(request, 'mod_customer.html', context=context)
else:
context = {'form': form}
return render(request, 'mod_customer.html', context=context)

This is after #BlackDoor step.
Your code might not reach form.save(). That is why the records are not being updated.
To know for sure do something like print(form.is_valid()) if this is False then do form.errors to see where it goes wrong.

Related

Django - Do I need to check for IntegrityErrors when validating a ModelForm?

I"ve got a simple question:
Do I need to listen for IntegrityErrors when I am already checking a submitted ModelForm's integrity with is_valid?
My code looks like this at the moment and I am thinking about removing the try catch:
def edit_object(request, object_id):
o = get_object_or_404(ObjectModel, pk=object_id)
if request.method == 'POST':
form = ObjectForm(request.POST, instance=o)
try:
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('namespace:startpage')
else:
return render(request, 'namespace/editpage.html', {'form': form,})
except IntegrityError:
return render(request, 'namespace/editpage.html', {'form': form,})
return render(request, 'namespace/editpage.html', {'form': ObjectForm(instance=o),})
Since I never even save my object if the data is not valid, I should never be able to produce an IntegrityError-exception, right?
Thanks in advance.

Delete record without accessing it directly

I am creating a data visualisation site in django and using the rest api for my data. Is there any way of deleting a record without accessing its url directly, as in this case it is impossible.
Something like
def employee_delete(request):
instance = Employee.objects.get(social_security=request.POST)
instance.delete()
return render(request, "dashboard.html")
This only works if you have access to the console as I learned, so I tried to access the data from a form like so
def employee_delete(request):
if request.method == "POST":
form = delete_EmployeeForm(request.POST, request.FILES)
if form.is_valid():
instance = Employee.objects.get(social_security=request.POST)
instance.delete()
return render(request, "dashboard.html")
else:
form = delete_EmployeeForm()
return render(request, "deleteemployee.html",{'form': form})
Would this work if I was able to be more specific about which piece of data I was accessing from the form? I got a typeError trying to use request.Post in that manner. That form contained a single field in 'social_security' from the Employee model.
Thanks
def employee_delete(request):
if request.method == "POST":
form = delete_EmployeeForm(request.POST, request.FILES)
if form.is_valid():
instance = Employee.objects.get(social_security=request.POST['social_security'])
instance.delete()
return render(request, "dashboard.html")
else:
form = delete_EmployeeForm()
return render(request, "deleteemployee.html",{'form': form})
use this in your view

How to add values to a form before submitting it with Django?

I need help with what might be a simple problem. I am writing a form to add a section to some unit. The unit will have X sections tied to it, sorted with indexes (indices?).
The problem arises when I try to pass the unit_id to the section. As the user will need to pass through the unit screen to add a section, I want it to be automatically assigned, it'll be in the URL too.
I am encountering problems adding it to the modelform, after submitting the value entered by the user.
def section_modify(request, unit_id, section_id=None):
unit = get_object_or_404(Models.Unit, id=int(unit_id))
if section_id is not None:
section = get_object_or_404(Models.Section, id=int(section_id))
else:
section = None
if request.method == "POST":
form = F.SectionForm(request.POST, instance=section)
if form.is_valid():
# I tried this part, but it didn't work:
# form.save(commit=False)
# form.unit_id = unit_id
form.save()
return HttpResponseRedirect('')
else:
form = F.SectionForm(instance=section)
return render(request, 'sectionEdit.html', {'form': form})
I am looking for the least hacky way to do this, django way.
Any help is much appreciated. Thank you for your time.
Try to add unit_id like this:
if form.is_valid():
# section will get unsaved model instance
# so you can assign property value and then save
section = form.save(commit=False)
section.unit_id = unit_id
section.save()
* UPDATED *
def section_modify(request, unit_id, section_id=None):
unit = get_object_or_404(Models.Unit, id=int(unit_id))
if section_id is not None:
section = get_object_or_404(Models.Section, id=int(section_id))
if section:
section.unit_id=unit.pk
section.save()
else:
section = None
if request.method == "POST":
form = F.SectionForm(request.POST, instance=section)
if form.is_valid():
if section:
form.save()
else:
section = form.save(commit=False)
section.unit_id=unit.pk
section.save()
return HttpResponseRedirect('')
else:
form = F.SectionForm(instance=section)
return render(request, 'sectionEdit.html', {'form': form})
So if we have section instance append unit_id to it else append unit'id after form submit.

Django handle new ManyToManyField items with get_or_create()

I have a model with a ManyToManyField and in my view I want to be able to add new options to the generated selectbox
How can I handle those new items with get_or_create function?
I want to check for form validity before saving it, but it will never be valid because I have to create all the new ManyToMany items.
In the meantime, I don't want to add new items if the form is not valid...
So I'm stuck with this not-working-code:
def add_entry(request):
if request.method == 'POST':
form = EntryForm(data=request.POST)
model_instance = form.save(commit=False)
for tag in model_instance.tags.all():
t, created = Tag.objects.get_or_create(author=request.user, title=tag.title)
model_instance.tags.add(t)
if form.is_valid():
model_instance.save()
return HttpResponseRedirect("/")
else:
form = EntryForm()
return render_to_response(
'add_entry.html',
{'form' : form },
context_instance=RequestContext(request))
EDIT:
my code is now
def add_entry(request):
if request.method == 'POST':
form = EntryForm(data=request.POST)
if form.is_valid():
model_instance = form.save(commit=False)
model_instance.save()
form.save_m2m()
return HttpResponseRedirect("/")
else:
print form.errors
else:
form = EntryForm()
return render_to_response(
'add_entry.html',
{'form' : form },
context_instance=RequestContext(request)
)
and i can save existing tags, but i can't dinamically add new ones...
I guess you are using some sort of JS to add the tags dynamically. I suggest you to go further and create an API endpoint where you can actually save the created tags so they can became a valid options of the selectbox.

Insert or update data with Django formsets

it's not clear to me how to manage formsets in Django. This is my views.py:
def newAd(request):
newAdFormSet = modelformset_factory(Ad)
if request.method == 'POST':
formset = newAdFormSet(request.POST, request.FILES)
if formset.is_valid():
formset.save()
return render_to_response('conf.html',
{'state':'Your ad has been successfull created.'},
context_instance = RequestContext(request),)
else:
formset = newAdFormSet()
return render_to_response('ad_form.html',
{'form':formset},
context_instance=RequestContext(request),)
It works but it always returns one prefilled form for each existing tuple plus, at the end, a blank form.
Now, i can't get how to say where it must return a blank form (to perform a new insert), and where it must instead return a single prefilled form (possibly passing the Ad's id) to perform an update.
modelformset_factory and formset helps to solve a lot, take your code for example
def newAd(request):
newAdFormSet = modelformset_factory(Ad, extra=1)
if request.method == 'POST':
formset = newAdFormSet(request.POST, request.FILES)
if formset.is_valid():
formset.save()
return render_to_response('conf.html',
{'state':'Your ad has been successfull created.'},
context_instance = RequestContext(request),)
else:
formset = newAdFormSet(queryset=Ad.objects.all())
return render_to_response('ad_form.html',
{'form':formset},
context_instance=RequestContext(request),)
Note the extra=1 in modelformset_factory line, it ensures there is only one extra blank form. And queryset=Ad.objects.all() in the second newAdFormSet inside else statement, it pre-fills forms for Ad objects from DB and correctly set PK in, mostly hidden, field for backend code to recognize submitted objects.
update
if you want to set Ad().codU to point to an User() instance, request.user for example, you could simply just set it by
instances = formset.save(commit=False)
for obj in instances:
obj.codU = request.user
obj.save()
I'm still not 100% clear what your question is, but it sounds like you don't want a formset at all. If you're only interested in adding or updating a single record at a time, you want a simple ModelForm, not a formset. So:
class AdForm(forms.ModelForm):
class Meta:
model = Ad
def add_update_ad(request, pk=None):
if pk is not None:
instance = Ad.objects.get(pk=pk)
else:
instance = Ad()
if request.POST:
form = AdForm(request.POST, instance=instance)
if form.is_valid():
new_instance = form.save()
return HttpResponseRedirect('my_confirmation_view')
else:
form = AdForm(instance=instance)
return render(request, 'ad_form.html', {'form': form})