Hamzah Zabin
Hamzah Zabin

Reputation: 93

Django - Populating Edit/Update Form With an Object's Preexisting Data

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: enter image description here

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:

enter image description here

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

Answers (1)

Jacinator
Jacinator

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:

  1. 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.

  2. 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

Related Questions