Issues with passing data to form

Hi there,

Hope everyone’s well.

I am stuck unfortunately… I am passing a database object to another page, where I want to allow a user to edit the database object and submit if required, but it only correctly submits the name of the object and the date it was created. The Boolean field ‘is_custom’ reverts to its default value, as does ‘description’, which remains ‘None’. Any ideas what I could be doing wrong?

==RELEVANT CODE==

See the below views:

def crudtask(request):
    # Retrieve all tasks from the database
    tasks = Tasks.objects.all()
 
    form = TaskForm()
    delete_form = DeleteTaskForm()
    update_form = UpdateTaskForm()
 
    if request.method == "POST":
        if 'add_task' in request.POST:  # Check if the add task form is submitted
            form = TaskForm(request.POST)
            if form.is_valid():
                form.save()
                return redirect('crud-redirect')
 
        elif 'delete_task' in request.POST:  # Check if the delete task form is submitted
            delete_form = DeleteTaskForm(request.POST)
            if delete_form.is_valid():
                taskid = delete_form.cleaned_data.get('taskid')
                try:
                    task = Tasks.objects.get(taskid=taskid)
                    task.delete()
                    messages.success(request, 'Task deleted successfully')
                except Tasks.DoesNotExist:
                    messages.error(request, 'Invalid form submission')
 
 
        elif 'update_task' in request.POST:
            taskid = request.POST.get('taskid')
            if taskid:
                return redirect('temp-update', pk=taskid)
 
 
        else:
           messages.error(request, 'Failed to delete task.')
 
    return render(request, "addtask.html", {"form": form, "tasks": tasks})
 
def temp_update(request, pk):
    task = get_object_or_404(Tasks, pk=pk)
    print(f"Task ID: {task.pk}, Name: {task.name}, Description: {task.description}, Is Custom: {task.is_custom}")
 
 
    if request.method == 'POST':
        form = UpdateTaskForm(request.POST, instance=task)
        if form.is_valid():
            form.save()
            return redirect('crud-redirect')  
    else:
        form = UpdateTaskForm(instance=task)
 
    print(form['description'].value())  
 
    return render(request, 'temp_update.html', {'form': form, 'task': task})

I am concerned with ‘update_task’, which redirects to the ‘temp_update’ view.

The form will initially be on this HTML page (addtask.html, view ‘crudtask’:

<!DOCTYPE html>
{% load static %}
 
<html lang="en">
 
<head>
 
  <meta charset="UTF-8" />
 
  <title>High and Tidy Cleaning App!</title>
 
  <meta name="viewport" content="width=device-width,initial-scale=1" />
 
  <meta name="description" content="" />
 
  <link rel="icon" href="{% static 'favicon.ico' %}">
 
  <link rel="stylesheet" type="text/css" href="{% static 'stylesaddtask.css' %}">
 
</head>
 
<body>
 
 
 
  <h2>Add or delete your task!</h2>
  <form action="{% url 'crud-redirect' %}" method="post">
    {% csrf_token %}
    <p>{{ form.name.label_tag }} {{ form.name }}</p>
    <p>{{ form.description.label_tag }} {{ form.description }}</p>
    <p>{{ form.is_custom.label_tag }} {{ form.is_custom }}</p>
    <button type="submit" name="add_task">Add Task!</button>
  </form>
 
 
  <h2>Existing Tasks:</h2>
  <table>
    <thead>
      <tr>
        <th>Name</th>
        <th>Description</th>
        <th>taskid</th>
        <th>is_custom</th>
        <th>task_created</th>
        <th>Delete task</th>
        <th>Update task</th>
        </tr>
    </thead>
    <tbody>
      {% for task in tasks %}
        <tr>
          <td>{{ task.name }}</td>
          <td>{{ task.description }}</td>
          <td>{{ task.taskid }}</td>
          <td>{{ task.is_custom }}</td>
          <td>{{ task.task_created }}</td>
          <td>
            <form action="{% url 'crud-redirect' %}" method="post" style="display: inline;">
            {% csrf_token %}
            <input type="hidden" name="taskid" value="{{ task.taskid }}">
            <button type="submit" name="delete_task">Delete Task!</button></form>
          </td>
          <td>
            <form action="{% url 'temp-update' task.taskid %}" method="post" style="display: inline;">
              {% csrf_token %}
              <input type="hidden" name="taskid" value="{{ task.taskid }}">
              <button type="submit" name="update_task">Update task</button>
            </form>
          </td>
        </tr>
      {% endfor %}
 
 
 
 
      </form>
    </tbody>
  </table>
 
</body>
 
</html>

and the page it directs to is (‘temp_update.html’, view ‘temp_update’):

<!-- templates/temp_update.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Update Task</title>
    <style>
        /* Your CSS styling here */
    </style>
</head>
<body>
    <div class="container">
        <h1>Update Task</h1>
 
        <!-- Display task details -->
        <div class="task-details">
            <h2>Current Task Details:</h2>
            <p><strong>Name:</strong> {{ task.name }}</p>
            <p><strong>Description:</strong> {{ task.description }}</p>
            <p><strong>Custom:</strong> {{ task.is_custom|yesno:"Yes,No" }}</p>
            <p><strong>Created on:</strong> {{ task.task_created }}</p>
        </div>
 
        <!-- Update form -->
        <form method="POST">
            {% csrf_token %}
            <p>{{ form.name.label_tag }} {{ form.name }}</p>
            <p>{{ form.description.label_tag }} {{ form.description }}</p>
            <p>{{ form.is_custom.label_tag }} {{ form.is_custom }}</p>
            <button type="submit">Update Task</button>
        </form>
 
 
        <a href="{% url 'crud-redirect' %}" class="back-link">Back to Task List</a>
    </div>
</body>
</html>

My forms are here:

from django import forms
from .models import Tasks  
 
class TaskForm(forms.ModelForm):
    class Meta:
        model = Tasks
        fields = ['name', 'description', 'is_custom']
 
class DeleteTaskForm(forms.Form):
        taskid = forms.IntegerField(widget=forms.HiddenInput())
        fields = ['taskid']
 
class UpdateTaskForm(forms.ModelForm):
    class Meta:
        model = Tasks
        fields = ['name', 'description', 'is_custom']

For comparison, the model these forms derive from is here:

class Tasks(models.Model):
    # Use AutoField as primary key
    taskid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=45)
    description = models.CharField(max_length=200, null=True, blank=True)
    is_custom = models.BooleanField(default=False)
    task_created = models.DateTimeField(auto_now_add=True)
 
    def __str__(self):
        return f'{self.name} - Description: {self.description}'

==/RELEVANT CODE==

Problem: When I go to update a task, it pulls through the name of the task and the creation date of the task, but it does not pull through information on the fields (‘is_custom’, ‘description’); these are shown by their default values ‘False’ and ‘None’ respectively.

When I add a print statement to show the description, this does show up in the console. All information is also present on the ‘addtask.html’ page, and is successfully rendered there.

So I can retrieve the data from the database no problem through console etc. but somehow the problem appears to be with the rendering in the HTML file.

I have been at this for a couple of days now going through the whole logic with a fine-tooth comb, but I am new and may be missing something obvious.

Any help would be appreciated. Thank you.

Welcome @Spiff_Crixley !

Please do not post images of code, or links to images of code.

When you need to share code or templates, copy / paste the code into the body of your post, between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code (or template, etc), then another line of ```. This forces the forum software to keep your code properly formatted.

No problem. Amended.

There are a couple different things here.

First, you’re not handling / showing errors in your form handling, making it difficult to see what’s going wrong.

Second, Your “Update task” button in addtask.html is doing a POST to the temp-update url. However, there’s no data in this form, only a taskid. So when the view executes, the if request.method == 'POST' is True, but form.is_valid is False. This causes the code to fall through to the return render(...) line, but with an empty form. (Why is the form empty? Because there was no data in the request.POST being submitted.)

You probably want your “Update task” button to be a link to that view, with the id as a url parameter, not a form being posted.

Hi Ken,

Appreciate you taking the time to look into this. I will see whether this fixes the issue. Great insight. Thank you.