Reputation: 93
I have an edit/update values form in Django, in which you need to choose the object you want to change its details from a drop down menu and then enter the new information you wanted to edit/update. When you choose an object from the dropdown menu the form looks like this:
I am trying to populate the edit form with the pre existing fields of the object that I chose from the dropdown menu to make it easier to make changes. it should look like this screenshot:
Any ideas how I can achieve that?
Views.py Code:
def tasks(request):
if request.user.is_superuser:
context = {
'tasks':Task.objects.all(),
'title': 'Tasks',
'addForm':AddNewTask(prefix = 'add'),
'editForm':EditTask(prefix = 'edit'),
}
else:
context = {
'tasks':Task.objects.filter(created_by=request.user),
'title': 'Tasks',
'addForm':AddNewTask(prefix = 'add'),
'editForm':EditTask(prefix = 'edit'),
}
if request.method =='POST':
if 'addNew'in request.POST:
addForm = AddNewTask(request.POST,prefix = 'add')
if addForm.is_valid():
task = addForm.save(commit=False)
task.created_by = request.user
task.save()
messages.success(request, f' Task Created Successfully ')
else:
messages.warning(request, 'Something Went Wrong !')
elif 'editExisting' in request.POST:
editForm = EditTask(request.POST,prefix = 'edit')
if editForm.is_valid():
taskID = editForm.cleaned_data['existing_task'].id
new_title = editForm.cleaned_data['title']
new_desc = editForm.cleaned_data['description']
new_status = editForm.cleaned_data['status']
object = Task.objects.get(id=taskID)
object.title = new_title
object.description = new_desc
object.status = new_status
object.save()
messages.success(request, f'Task #{taskID} Has Been Edited Successfully!')
else:
messages.warning(request, 'Something Went Wrong !')
return render(request,'ticketing/tasks.html',context)
forms.py Code:
class EditTask(forms.Form):
existing_task = forms.ModelChoiceField(Task.objects.order_by('id'),label= 'Existing Task')
title = forms.CharField(max_length=100,required=True,label ='Title')
description = forms.CharField(widget=forms.Textarea,label='Description')
status = forms.ChoiceField(choices=Status,label='Change Status')
models.py Code:
class Task(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=100)
description = models.TextField()
last_modified = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(User,on_delete=models.PROTECT)
status = models.CharField(choices=Status,max_length=2,default='O')
def __str__(self):
return str(self.title)
Upvotes: 0
Views: 1437
Reputation: 1413
Here's the issue.
You load the page and render the form. Then you choose an object representing a row of data with which to populate the form. At this point the form is already rendered.
You have two options:
Restructure your workflow so that the choice field and the edit form are on separate page loads. You load the dropdown field, choose an object, and submit the form, which then re-renders the form (200 on POST or redirect) with the data populated.
Handle the data through JavaScript on the client side. You will need to watch the dropdown field and then populate the form with data through JavaScript.
A. You can either pass ALL of the data for all of the choices to the JavaScript on the initial page load, which could be a lot of data for a large table, or...
B. You can retrieve the data through an API when the dropdown is changed.
I would favour the first option. Present the user with the dropdown and a next button (/edit/). Use that form data to redirect to a page with the edit form and a save button (/edit/<id>/). Use that form data to update the object and redirect back to the dropdown page (/edit/).
Upvotes: 2