My Django website not showing any forms when I edit - python

I'm building a website using Django.
And for somereason, the dictionary using all the forms is not showing at all..
When I click my Edit button the modal is showing without the forms...
forms.server_id needs to contain all the forms using server_id...
the server_id I use to show the previous data when I edit.
But for some reason, it doesn't show any form at all...
index.html -
{% load static i18n util_filters %}
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs4/jq-3.2.1/jq-3.2.1/dt-1.10.16/af-2.2.2/b-1.4.2/fc-3.2.3/fh-3.1.3/kt-2.3.2/r-2.2.0/rg-1.0.2/rr-1.2.3/sc-1.4.3/sl-1.2.3/datatables.min.css"/>
<script src="https://use.fontawesome.com/3c2c6890cf.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/jq-3.2.1/jq-3.2.1/dt-1.10.16/af-2.2.2/b-1.4.2/fc-3.2.3/fh-3.1.3/kt-2.3.2/r-2.2.0/rg-1.0.2/rr-1.2.3/sc-1.4.3/sl-1.2.3/datatables.min.js"></script>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="{% url 'serverlist' %}">DevOps Map</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="{% url 'serverlist' %}">Servers</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'serverlist' %}">Switches</a>
</li>
</ul>
</div>
</nav>
<style type="text/css">
.wrapper {
display:flex;
}
</style>
</head>
<body>
<div class="container">
<br>
<center><h1 class="display-4">DevOps Server List</h1></center>
<br>
<center><button type="button" class="save btn btn-outline-success btn-lg" data-toggle="modal" data-target=".AddServer">Add Server <i class="fa fa-server fa-lg" aria-hidden="true"></i></button></center>
<table class="table table-hover table-bordered table-condensed" cellspacing="0" width="1300" id="ServerTable">
<thead>
<tr>
<th><center> #</center></th>
<th><center> Server Name </center></th></center>
<th><center> Owner </center></th></center>
<th><center> Project </center></th></center>
<th><center> Description </center></th></center>
<th><center> IP Address </center></th></center>
<th><center> ILO </center></th></center>
<th><center> Rack </center></th></center>
<th><center> Status </center></th></center>
<th><center> Actions </center></th></center>
</tr>
</thead>
<tbody>
{% for server in posts %}
<tr>
<div class ="server">
<td></td>
<td><center>{{ server.ServerName }}</center></td>
<td><center>{{ server.Owner }}</center></td>
<td><center>{{ server.Project }}</center></td>
<td><center>{{ server.Description }}</center></td>
<td><center>{{ server.IP }}</center></td>
<td><center>{{ server.ILO }}</center></td>
<td><center>{{ server.Rack }}</center></td>
<td><h4><span class="badge badge-success">Online</span></h4></td></center>
<td>
<button type="button" class="btn btn-outline-danger" data-toggle="modal" href="#delete-server-{{server.id}}"
data-target="#Del{{server.id}}">Delete <i class="fa fa-trash-o"></i></button>
<button type="button" class="btn btn-outline-primary" data-toggle="modal" href="#edit-server-{{server.id}}"
data-target="#Edit{{server.id}}"> Edit <i class="fa fa-pencil"></i></button>
<div id ="Del{{server.id}}" class="modal fade" role="document">
<div class="modal-dialog" id="delete-server-{{server.id}}">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Delete Confirmation</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form action="{% url 'delete_post' server.id %}" method="post">{% csrf_token %}
<h6>Are you sure you want to delete {{ server.ServerName }}?</h6>
<br>
<center><input type="submit" class="btn btn-danger btn-md" value="Confirm"/>
<button type="submit" class="btn btn-secondary" data-dismiss="modal">Cancel</button></center>
</form>
</div>
</div>
</div>
</div>
<div class="modal fade bd-example-modal-sm" id="Edit{{server.id}}" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Edit Server <strong>{{ server.ServerName }}</strong> </h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{% with server.id as server_id %}
{% with forms|get_by_key:server_id as edit_form %}
<form action="{% url 'edit_post' server_id %}" method="post"> {% csrf_token %}
<!--<center> {{ edit_form.as_p }} </center> -->
{% for field in forms.server_id %}
<div class="fieldWrapper">
{{ field.errors }}
<!-- {{ field.label_tag }} -->
<small><strong>{{ field.html_name }}<p align="left"></b> {{ field }}</small> </strong>
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
</div>
<div class="wrapper">
<h2><button type="submit" class="save btn btn-success btn-lg">Confirm</button></h2>
<h2><button type="submit" class="btn btn-secondary btn-lg" data-dismiss="modal">Cancel</button></h2>
</div>
</form>
{% endwith %}
{% endwith %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</h5>
</table>
<div class="modal fade AddServer" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add Server</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form method="post" novalidate> {% csrf_token %}
<!--<center> {{ form.as_p }} </center> -->
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
<!-- {{ field.label_tag }} -->
<small><strong>{{ field.html_name }}</strong></small><p align="left"></b> {{ field }} </p>
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
</div>
<div class="wrapper">
<h2><button type="submit" class="save btn btn-success btn-lg" >Confirm</button></h2>
<h2><button type="submit" class="btn btn-secondary btn-lg" data-dismiss="modal">Cancel</button></h2>
</div>
</div>
</form>
</div>
</div>
</div>
views.py -
# Create your views here.
from django.shortcuts import render_to_response
from django.shortcuts import get_object_or_404
from django.shortcuts import render, redirect
from django.template import RequestContext
from django.views.generic import TemplateView, UpdateView, DeleteView, CreateView
from DevOpsWeb.forms import HomeForm
from DevOpsWeb.models import serverlist
from django.core.urlresolvers import reverse_lazy
from simple_search import search_filter
from django.db.models import Q
class HomeView(TemplateView):
template_name = 'serverlist.html'
def get(self, request):
form = HomeForm()
query = request.GET.get("q")
posts = serverlist.objects.all()
forms = {}
if query:
posts = serverlist.objects.filter(Q(ServerName__icontains=query) | Q(Owner__icontains=query) | Q(Project__icontains=query) | Q(Description__icontains=query) | Q(IP__icontains=query) | Q(ILO__icontains=query) | Q(Rack__icontains=query))
else:
posts = serverlist.objects.all()
#for post in posts:
# form = HomeForm(instance=post)
for post in posts:
forms[post.id] = HomeForm(instance=post)
args = {'form' : form,'forms': forms, 'posts' : posts}
#args = {'form' : form, 'forms': forms, 'posts' : posts}
return render(request, self.template_name, args)
def post(self,request):
form = HomeForm(request.POST)
posts = serverlist.objects.all()
if form.is_valid(): # Checks if validation of the forms passed
post = form.save(commit=False)
post.save()
#form = HomeForm()
return redirect('serverlist')
for post in posts:
forms[post.id] = HomeForm(instance=post)
args = {'form' : form, 'forms': forms, 'posts' : posts}
#args = {'form' : form,'forms': forms, 'posts' : posts}
return render(request, self.template_name,args)
class PostDelete(DeleteView):
model = serverlist
success_url = reverse_lazy('serverlist')
class PostEdit(UpdateView):
template_name = 'serverlist.html'
model = serverlist
form_class = HomeForm
#fields = ['ServerName','Owner','Project','Description','IP','ILO','Rack','Status']
success_url = reverse_lazy('serverlist')
#def get_object(self):
# obj = get_object_or_404(Calification, pk=self.request.POST.get('pk'))
# return obj

This :
{% with server.id as server_id %}
{# ... #}
{{ forms.server_id.as_p }}
just cannot work - it will look for forms["server_id"] (=> use the literal string "server_id" as key). You will need a custom template filter, such as the one described here. And as Daniel Roseman rightly mentions in a comment, you'll have to pass whatever server is supposed to be to your template's context too.
Also note that you're going to get a NameError in HomeView.post - you copy-pasted part of the code filling in your posts dict but not the part instanciating it. You should really factor this out instead of copy-pasting.

Related

Django UpdateView Bootstrap Modal - i've got empty form in modal window

I've got empty Bootstrap modal form with Django UpdateView(CBV)
The most important question without using js , I will not be able to display data in a modal window? (I only use bootstrap.bundle.min.js in base.html)
Modal window show fields of empty form
view.py
class HistoryPamentsByService(ListView):
model=Payments
form_class=PaymentsForm
template_name ='myflat/history_by_service.html'
context_object_name='flats'
slug_url_kwarg = 'slug'
def get_context_data(self, **kwargs):
context=super().get_context_data(**kwargs)
form=PaymentsForm()
payments=Payments.objects.filter(flats_id=self.kwargs['flats_id'])
context['form']=form
return context
def get_form(self,*args,**kwargs):
super().get_form(*args, **kwargs)
form=PaymentsForm()
return form
def get_queryset(self):
return Payments.objects.filter(slug=self.kwargs['slug'],flats_id=self.kwargs['flats_id'])
class UpdatePayments(UpdateView):
model=Payments
pk_url_kwarg='pk'
template_name='myflat/update_modal.html'
context_object_name='name_flat'
fields=['name_service','amount_of_bill',
'amount_of_real',
'date_of_bill',
'date_of_payment',
'status_payment',
'comments',
'bill_save_pdf']
def get_success_url(self):
return reverse('HistoryPamentsByService',
kwargs={'slug':self.object.slug,
'flats_id': self.object.flats_id})
urls.py
urlpatterns = [ path('history_by_service/<slug:slug>/<int:flats_id>/',
HistoryPamentsByService.as_view(),name='HistoryPamentsByService'),
path('UpdatePayments/<int:pk>/',UpdatePayments.as_view(),name='UpdatePayments'),
]
template
history_by_service.html (for ListView)
{%extends "base.html"%}
{%block content%}
{% for flat in flats %}
<tr>
<td scope="row">{{ forloop.counter }} </td>
<td>{{flat.name_service}}</td>
<td>{{flat.amount_of_bill}}</td>
<td>{{flat.amount_of_real}}</td>
<td>{{flat.date_of_bill}}</td>
<td>{{flat.date_of_payment}}</td>
<td>{{flat.get_status_payment_display}}</td>
<td>{{flat.comments}}</td>
<td>{{flat.bill_save_pdf}}</td>
<td>
<form method="post" action="{% url 'UpdatePayments' flat.pk %}" enctype="multipart/form-data">
{% csrf_token %}
<button type='button' class='btn btn-success btn-sm' id="update_modal"
data-bs-toggle="modal" data-bs-target="#update_modal{{flat.pk}}">
<i class="fa-regular fa-pen-to-square fa-fw"></i>Edit</button>
{% include "myflat/update_modal.html" %}
</form>
{% endfor %}
{% endblock content %}
template
update_modal.html
<div class="modal fade" id="update_modal{{flat.pk}}" data-bs-backdrop="static"
data-bs-keyboard="false" tabindex="-1" aria-labelledby="update_modal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content" style="width:auto">
<div class="modal-header">
<h5 class="modal-title " id="update_modalLabel">{{flat.name_flat}}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form method="post" action="{% url 'UpdatePayments' flat.pk %}" enctype="multipart/form-data">
<div class="modal-body">
{% csrf_token %}
{% for field in form %}
{{field}}
{% endfor %}
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" >
<i class="fa-solid fa-trash fa-fw" ></i>Save</button>
<button type="button" class="btn btn-warning"
data-bs-dismiss="modal">
<i class="fa-regular fa-circle-xmark"></i>Close</button>
</div>
</div>
</form>
</div>
</div>
</div>
I try add in UpdatePayments(UpdateView) next code:
class UpdatePayments(UpdateView):
model=Payments
pk_url_kwarg='pk'
form_class=PaymentsForm
template_name='myflat/update_modal.html'
context_object_name='name_flat'
def get_context_data(self, **kwargs):
context= super().get_context_data(**kwargs)
obj=Payments.objects.get(pk=self.kwargs['pk'])
form=PaymentsForm(self.request.POST or None ,instance=obj)
context['form']=form
return context
but still nothing in Modal is empty fields!!!
What's wrong, any helps,please!!!

Django class based signup view form not show up in bootstrap modal

I try to look up my signup view as a bootstrap modal but when click form doesn't show
class SignUpView(CreateView):
form_class = UserCreationForm
template_name = 'avapp/signup.html'
success_message = 'Success: Sign up succeeded. You can now Log in.'
success_url = reverse_lazy('index')
views.py
{% extends 'base.html' %}
{% load static %}
{% block content %}
<h1 style="text-align: center;color: #568203 " > Avakado App</h1>
<center>
<a class="btn btn-outline-success" data-bs-toggle="modal" data-bs-target="#exampleModal " >
<img style="text-align: center" src="{% static '1_org.jpg' %}" width="300" height="450" >
</a>
</center>
{% endblock %}
index.html
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form action="/signup" method="POST">
<div class="modal-body">
{% csrf_token %}
{{form}}
</div>
</form>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
signup.html
this is the modal form looks like
Can I figure it out without using Ajax or something else or do I have to change my signup view from class based views to something else

Why does this weird "content" attribute has no file associated with it error comes up in Django?

This question might have been asked several times before but I referred to them but I was not able to fix my problem. That is why I am having to ask it. So, I have a Django app where users can set up tasks. They can also upload attachments. I was successfully able to implement this but for some reason it has stopped working now. These are the relevant code:
models.py
def get_attachment_dir(instance, filename):
return f"users/{instance.parent_task.creator.username}_{instance.parent_task.creator.pk}/task_attachments/{instance.parent_task.pk}/{filename}"
class Attachments(models.Model):
content = models.FileField(null=True, blank=True, upload_to=get_attachment_dir, help_text="Add important documents or pictures")
parent_task = models.ForeignKey(ToDo, on_delete=models.CASCADE)
uploaded_on = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"Attachments of {self.parent_task.title}"
forms.py
class TaskAttachmentForm(forms.ModelForm):
class Meta:
model = Attachments
fields = ["content"]
Relevant part of the view function that renders the attachment form
if request.method == "POST":
attachment_form = TaskAttachmentForm(request.POST, request.FILES)
if attachment_form.is_valid():
# Making sure we get no Integrity Errors
attachment_form.instance.parent_task = todo
attachment_form.save()
if not todo.has_attachments:
todo.has_attachments = True
todo.save()
messages.success(request, "Your files were uploaded successfully")
else:
attachment_form = TaskAttachmentForm()
attachments = Attachments.objects.filter(parent_task=todo)
context = {
"todo": todo,
"note_form": ToDoNotesForm(),
"note": note,
"subtask_form": SubTaskForm(),
"attachment_form": attachment_form,
"subtasks": subtasks,
"due_form": DueDateForm(),
"title": todo.title,
"percentage": percentage,
"attachments": attachments
}
return render(request, "ToDo/detailed_view.html", context=context)
detailed_view.html relevant code where attachments are handled
{% if attachments %}
<div id="attachments-section" class="table-responsive dark-mode-assist-section">
<table class="table dark-mode-assist-section">
<thead>
<tr>
<th>File</th>
<th>Uploaded on</th>
<th>View/Download</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{% for attachment in attachments %}
<tr class="list-group-item" id="attachment-{{ attachment.pk }}">
<td>{{ attachment.content|getfilename }}</td>
<td>{{ attachment.uploaded_on|date:"F d"}}</td>
<td><a class="btn btn-success" href="{{ attachment.content.url }}">Click me</a></td>
<td>
<button style="font-size: 2.5ch;" data-toggle="modal" data-target="#exampleModalCenter{{ attachment.pk }}" class="btn btn-outline-danger">
<i class="fa fa-trash"></i>
</button>
</td>
</tr>
<div class="modal fade" id="exampleModalCenter{{ attachment.pk }}" tabindex="-1" role="dialog"
aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content dark-mode-assist-section">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">Confirm the deletion</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Are you sure you want to delete this attachment?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button data-dismiss="modal" onclick="deleteItem('attachment', {{ attachment.pk }})" type="submit"
class="btn btn-danger">Yes, I am sure</button>
</div>
</div>
</div>
</div>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
<a class="btn btn-outline-info" data-toggle="collapse" href="#multiCollapseExample-attachments" role="button"
aria-expanded="false" aria-controls="multiCollapseExample">
Upload attachments
</a>
<div class="row">
<div class="col">
<div class="collapse multi-collapse" id="multiCollapseExample-attachments">
<br>
<div class="card card-body dark-mode-assist-section">
<div class="content section">
<form method="POST" name="attachment-{{ todo.pk }}" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group dark-mode-assist">
<legend class="border-bottom mb-4">Add documents</legend>
{{ attachment_form|crispy }}
<input type="hidden" name="title" value={{ todo.pk }}>
<p id="hidden-parent-task-pk" style="display:none">{{ todo.pk }}</p>
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info btn-lg" type="submit"><i class="fas fa-upload"></i></button>
</div>
</form>
</div>
</div>
</div>i
</div>
</div>
I am saying that this seems weird is because I was able to access attachment.content when running the same command under python manage.py shell
Any help is seriously appreciated and needed. Thanks a lot.

Django - Confirmation popup

I'm trying to write a code for deleting an item. But before deleting it i want to popup a message to the user like "are you sure you want to delete?".
I want to delete the item by its ID.
I wrote this code, but i pretty sure its not how it should be.
Please guide me what to do.
HTML FILE
<div id="film_box">
{% if films %}
{% for film in films %}
<div class="card" style="width: 18rem;">
{% if film.image%}
<img src="{{ film.image.url }}" class="card-img-top" alt="...">
{% endif %}
<div class="card-body">
<h5 class="card-title">{{ film.title}}</h5>
<p class="card-text">{{ film.category_name }}</p>
<p class="card-text">{{ film.country_name }}</p>
<p class="card-text">{{ film.director }}</p>
<p class="card-text">{{ film.release_date }}</p>
</div>
<div class="card-body">
{% if request.user.is_superuser %}
<ul style="list-style:none;">
<li>Modify the director
</li>
<li>Modify the film</li>
<li><button onclick="document.getElementById('btn_delete').style.display='block'"
name="{{ film.id }}" class="btn btn-danger">DELETE</button></li>
</ul>
{% endif %}
<!--popup message-->
<div id="btn_delete" class="modal">
<span onclick="document.getElementById('btn_delete').style.display='none'" class="close" title="Close
Modal">×</span>
<form class="modal-content" action="/delete/{{film.id}}">
<div class="container">
<h1>Delete film</h1>
<p>Are you sure you want to delete the film?</p>
<div class="clearfix">
<button type="button" onclick="document.getElementById('btn_delete').style.display='none'" class="cancelbtn">Cancel</button>
<button href="{% url 'delete_film' film.id %}" onclick="document.getElementById('btn_delete').style.display='none'" class="deletebtn">Delete</button>
</div>
</div>
</form>
</div>
{% endfor%}
{% endif %}
JAVASCRIPT FILE
// Get the modal
var modal = document.getElementById('btn_delete');
console.log(model.name)
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
I want to pass the ID in the url, so i can catch it on the python file and manipulate it.
Should i use Javascript?
This is how I would do it. Please note the code is not tested, however the principles should give you a glimpse of understanding of how to proper do it.
from django.http import JsonResponse
from django.views import generic
# urls.py
urlpatterns = [
re_path(r'^delete/(?P<pk>.+)/$', views.DeleteFilmView.as_view(), name='delete'),
]
# models.py
class Film(models.Model):
# ...
def get_delete_url(self):
return reverse('film:delete', args=(self.pk,))
# views.py
class DeleteFilmView(generic.DeleteView):
template_name = 'delete_confirmation.html'
model = Film
context_object_name = 'film'
def delete(self, *args, **kwargs):
self.object = self.get_object()
success_url = self.get_success_url()
self.object.delete()
return JsonResponse({'messages': 'Deleted'})
<!--html file-->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Delete Film</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div id="film_box">
{% if films %}
{% for film in films %}
<div class="card" style="width: 18rem;">
{% if film.image%}
<img src="{{ film.image.url }}" class="card-img-top" alt="...">
{% endif %}
<div class="card-body">
<h5 class="card-title">{{ film.title}}</h5>
<p class="card-text">{{ film.category_name }}</p>
<p class="card-text">{{ film.country_name }}</p>
<p class="card-text">{{ film.director }}</p>
<p class="card-text">{{ film.release_date }}</p>
</div>
<div class="card-body">
{% if request.user.is_superuser %}
<ul style="list-style:none;">
<li>Modify the director
</li>
<li>Modify the film</li>
<li>Delete</li>
</ul>
{% endif %}
</div>
</div>
</div>
<script type="text/javascript">
(function () {
$('.deletePopup').on('click',function(){
$('.modal-body').load('content.html',function(){
$('#myModal').modal({show:true});
});
});
$('body').on('click', '.delete-film', function(e) {
// make sure you listen on the body and not on the element, because the element doesnt exist when
// DOM is created.
e.preventDefault():
$.ajax({
url: $(this).attr('href');,
type: 'DELETE',
dataType: 'json',
success: function(result) {
// show success message, ie: using toastr
// remove the film from DOM
// close the modal
}
})
})
})();
</script>
<!--delete_confirmation.html-->
<p>Are you sure you want to delete {{ film.title}}?</p>
<a class="delete-film" href="{{ film.get_delete_url }}">Delete</a>
Cancel

Why the form is not JSON serializable?

I am using Django and I am trying when a button is clicked to get data from the database and fill a form with them through AJAX.
I get the error TypeError: Object of type 'EditProductForm' is not JSON serializablefrom the edit_product_view in my views.py
Below is the code I am working with:
-urls.py
from django.conf.urls import url
from . import views
app_name = "products"
urlpatterns = [url(r'^products', views.ProductsView.as_view(), name="products"),
url(r"^product/new", views.add_new_product_view, name="add_new_product"),
url(r"^product/(?P<id>[0-9]+)/edit/", views.edit_product_view, name="edit_product")]
-views.py
from django.views.generic import DetailView, ListView, TemplateView
from django.http import JsonResponse
from django.shortcuts import render, get_object_or_404
from . import models
from products.forms import AddNewProductForm, EditProductForm
def index(request):
return render(request, 'products/products.html')
class ProductsView(ListView):
context_object_name = "products"
model = models.Product
template_name = "products/products.html"
form = AddNewProductForm()
def get_context_data(self, **kwargs):
context = super(ProductsView, self).get_context_data(**kwargs)
context["products"] = models.Product.objects.all().order_by("title")
context["form"] = self.form
return context
def add_new_product_view(request):
if request.method == "POST":
form = AddNewProductForm(request.POST)
if form.is_valid():
form.save(commit=True)
return JsonResponse({'msg': 'Data saved'})
else:
print("ERROR FORM INVALID")
return JsonResponse({'msg': 'ERROR FORM INVALID'})
else:
form = AddNewProductForm()
return JsonResponse({'form': form})
def edit_product_view(request, id):
print(request.method)
instance = get_object_or_404(models.Product, id=id)
form = EditProductForm(instance=instance)
if request.method == "POST":
form = EditProductForm(request.POST, instance=instance)
if form.is_valid():
form.save(commit=True)
return JsonResponse({'form': form})
else:
print("ERROR FORM INVALID")
return JsonResponse({'form': form})
-products.html
{% extends "products/base.html" %}
{% load static %}
{% block title %}My Products{% endblock %}
{% block content %}
<div class="container" id="my-products-table-container">
<h2 class="text-left caption">Add, view and edit products</h2>
<hr>
<table class="table table-striped table-sm table-bordered" id="my-products-table">
<thead class="thead-inverse">
<tr class="head-row">
<th>Title</th>
<th>Description</th>
<th>Year</th>
<th>Manufacturer</th>
</thead>
<tbody>
{% for product in products %}
<tr class="table-row">
<td>{{ product.title }}</td>
<td>{{ product.description }}</td>
<td>{{ product.year_manufactured }}</td>
<td>{{ product.manufacturer }}</td>
<td><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addNewProductModalForm">Add New product</button></td>
<td><button onclick="findMyForm({{ product.pk }})">Update product</button></td>
{% endfor %}
</tbody>
</table>
</div>
<!-- Modal Add New Product-->
<div class="modal fade" id="addNewProductModalForm" tabindex="-1" role="dialog" aria-labelledby="addNewProductModalFormLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<form class="form" id="add_new_product_form">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addNewProductModalFormLabel">Add New Product</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{% csrf_token %}
{{ form.as_p }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="addNewProduct()">Submit</button>
</div>
</div>
</form>
</div>
</div>
<!-- Modal Edit-->
<div class="modal fade" id="editProductModalForm" tabindex="-1" role="dialog" aria-labelledby="editProductModalFormLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<form class="form" id="edit_product_form" >
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editProductModalFormLabel">Edit Product</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{% csrf_token %}
<div id='showForm'></div>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-primary" value="Submit!">
</div>
</div>
</form>
</div>
</div>
<!-- JS Scripts -->
<script src="{% static "products/js/addProduct.js" %}"></script>
<script>
function findMyForm(productKey) {
$('#editProductModalForm').modal('show');
$.ajax({
type: 'GET',
url: '/product/' + productKey + '/edit/',
success: function(res) {
$("#showForm").html(res);
}
})}
</script>
{% endblock %}
-addProduct.js
function addNewProduct(e) {
var addNewProductForm = $("#add_new_product_form");
$.ajax({
type: 'POST',
url: '/product/new/',
data: addNewProductForm.serialize(),
success: function(res){
alert(res['msg'])
}
})
}
What happens is that when I click <button onclick="findMyForm({{ product.pk }})">Update product</button> the function findMyForm({{ product.pk }}) runs.
Then a get request is called on '/product/' + productKey + '/edit/' through AJAX, based on the urls.py and views.py, edit_product_view is called to pass the form which is filled with the appropriate data.
At this point, it says that TypeError: Object of type 'EditProductForm' is not JSON serializable. I can't figure it out.
The object 'EditProductForm' is not JSON serializable, what you need is to return the form as HTML str, change your views.py:
from
return JsonResponse({'form': form})
to
return HttpResponse(form.as_p()) # return form as html str

Categories