Issue
I am trying to build a ToDo List in Djanjo and I am having issues while trying to build the edit view functionality, below is my home.html file
<div class="col-md-7 col-lg-7" style="height: 450px; overflow: scroll;">
<!-- List of all the tasks for the day -->
{% for task in tasks %}
<div class="card m-1">
<div class="card-body">
<span id="task_{{ task.pk }}_text">{{ task.task }}</span>
<span style="position: relative; float: right;">
<a href="{% url 'mark_as_done' task.pk %}"class="btn btn-success"><i class="fa fa-check"></i> Mark as Done</a>
<a href="{% url 'delete_task' task.pk %}" class="btn btn-danger"><i class="fa fa-trash"></i></a>
<!-- When this button is clicked, a textbox/form will appear, after it appears and you press submit task
is updated -->
<a onclick="showTextBox('{{ task.pk }}')" class="btn btn-primary"><i class="fa fa-pencil"></i></a>
<form id="textbox_{{ task.pk }}" onsubmit="saveValue(event, '{{ task.pk }}')" method="post">
{% csrf_token %}
<input type="text" id="inputValue_{{ task.pk }}" name="edited_task" placeholder="Update task">
<input type="submit" value="Submit">
</form>
</span>
</div>
</div>
{% endfor %}
</div>``
Next is my script, where I try to send the data to the backend
<script>
function showTextBox(key){
/*console.log(100);
console.log(`textbox_${key}`);*/
var textbox = document.getElementById(`textbox_${key}`);
textbox.classList.toggle('hidden-textbox');
}
function saveValue(event,key){
/*each task object has a primary key associated to it*/
event.preventDefault();
var primary_key=key;
var enteredValue = document.getElementById(`inputValue_${primary_key}`).value;
const base="{% url 'edit' 123 %}".slice(0, -4);
const url=`${base}${primary_key}/`;
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': '{{ csrf_token }}'
},
body: JSON.stringify({ value: enteredValue }),
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
}
</script>
Below is my urls.py
from django.urls import path
from . import views
urlpatterns=[
path('addTask/',views.addTask, name="addTask"),
path('mark_as_done/<int:pk>',views.mark_as_done, name="mark_as_done"),
path('mark_as_undone/<int:pk>',views.mark_as_undone, name="mark_as_undone" ),
path('edit/<int:pk>/',views.edit, name="edit"),
path('delete_task/<int:pk>/',views.delete_task, name="delete_task")
]
below is the views.py
def edit(request,pk):
enteredValue= request.POST.get('edited_task')
get_task=get_object_or_404(Task,pk=pk)
get_task.task=enteredValue
get_task.save()
return redirect('home')
and last but not least is the models.py
from django.db import models
# Create your models here.
class Task(models.Model):
task = models.CharField(max_length=300)
is_completed= models.BooleanField(default=False)
created_at=models.DateTimeField(auto_now_add=True)
updated_at=models.DateTimeField(auto_now=True)
def __str__(self):
return self.task
Everything bar the edit function is working as intended. Any ideas on what the issue could be?
I tried trouble shooting and debugging the code, and I think it may have to do with the url in my fetch, but I have tried so many different variations and nothing is working. I want the task to be changed to whatever you submit in the form.
Solution
It seems that the issue IntegrityError
will be raised if your enteredValue
is of None type. Make sure you are sending in valid value.
HANDLE JSON PAYLOAD
In addition to, modify your edit
view. Since you are not using forms directly but via fetch api, you cannot use request.POST.get
to get your edited_task
data as this will only work if your content_type is set to application/x-www-form-urlencoded
. Now, you can change your content type in your javascript and also your payload encoding if you want.
But since you are opting to use application/json
you have to extract the json payload from the request.body
attribute instead like this:
import json # do this at the top
from django.views.decorators.http import require_POST # move to top
@require_POST
def edit(request,pk):
data = json.loads(request.body)
enteredValue= data.get('edited_task')
get_task=get_object_or_404(Task,pk=pk)
if enteredValue is not None:
get_task.task = enteredValue
get_task.save()
get_task.task=enteredValue
get_task.save()
return redirect('home')
This way you will only update the task if a non-NULL value is provided which will avoid the not NULL CONSTRAINT
error.
Also, in your javascript call (fetch api
), your payload does not have the correct key. Your view is expecting edited_task
.
Change this portion of the code:
body: JSON.stringify({ value: enteredValue }),
To this:
body: JSON.stringify({ edited_task: enteredValue }),
Answered By - Mess
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.