NoReverseMatch error for update and delete view - django

I've a trouble with an update view and a delete view. Below the code:
views.py
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.text import slugify
from .forms import BlogTagForm
from .models import BlogTag
def updateBlogTag(request, slug_tag=None):
update_tag = get_object_or_404(BlogTag, slug_tag=slug_tag)
form = BlogTagForm(request.POST or None, instance=update_tag)
if form.is_valid():
update_tag = form.save(commit=False)
update_tag.slug_tag = slugify(update_tag.tag_name)
update_tag.save()
return redirect('tag_list')
context = {
'form': form,
}
template = 'blog/editing/create_tag.html'
return render(request, template, context)
def deleteBlogTag(request, slug_tag):
if request.method == 'POST':
tag = BlogTag.objects.get(slug_tag=slug_tag)
tag.delete()
return redirect('tag_list')
models.py
from django.db import models
from django.urls import reverse
class BlogTag(models.Model):
tag_name = models.CharField(
'Tag',
max_length=50,
help_text="Every key concept must be not longer then 50 characters",
unique=True,
)
slug_tag = models.SlugField(
'Slug',
unique=True,
help_text="Slug is a field in autocomplete mode, but if you want you can modify its contents",
)
def __str__(self):
return self.tag_name
def get_absolute_url(self):
return reverse("single_blogtag", kwargs={"slug_tag": self.slug_tag})
class Meta:
ordering = ['tag_name']
forms.py
from django import forms
from .models import BlogTag
class BlogTagForm(forms.ModelForm):
tag_name = forms.CharField(
max_length=50,
help_text="<small>Write a tag here. The tag must be have max 50 characters.</small>",
widget=forms.TextInput(
attrs={
"placeholder": "Tag",
"type": "text",
"id": "id_tag",
"class": "form-control form-control-lg",
}
),
)
class Meta:
model = BlogTag
fields = ["tag_name"]
urls.py
path("update-tag/", views.updateBlogTag, name='update_tag'),
path("delete-tag/", views.deleteBlogTag, name='delete_tag'),
tag_list.html
<table class="table table-striped shadow">
<thead>
<tr>
<th>Tag</th>
<th>Related Posts</th>
<th class="text-center">Actions</th>
</tr>
</thead>
<tbody>
{% for tag in tag_list %}
<tr>
<td>{{ tag.tag_name }}</td>
<td>{{ tag.tag_blogpost.count }}</td>
<td>
<div class="row justify-content-md-center">
<a class="btn btn-success btn-sm mx-1" href="{#% url 'update_tag' slug_tag=tag.slug_tag %#}">Update</a>
<button class="btn btn-danger btn-sm mx-1" type="button" data-toggle="modal" data-target="#deleteModal">Delete</button>
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title text-center" id="deleteModalLabel">Delete Request</h2>
</div>
<div class="modal-body">
<h3>Are you sure to delete this tag?</h3>
<h1 class="py-4"><em><strong>{{ tag.tag_name }}</strong></em></h1>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" data-dismiss="modal">No, don't do this</button>
<form action="{% url 'delete_tag' tag.slug_tag %}" method="POST">
{% csrf_token %}
<button class="btn btn-danger btn-sm" type="submit" name="button">Yes, delete it</button>
</form>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
I've used the same type of code for another views without problems but in this case I've this error:
UPDATE VIEW NoReverseMatch at /blog/tags/
Reverse for 'update_tag' with keyword arguments '{'slug_tag':
'altro-tag'}' not found. 1 pattern(s) tried: ['blog/update\-tag/$']
DELETE VIEW NoReverseMatch at /blog/tags/
Reverse for 'delete_tag' with arguments '('altro-tag',)' not found. 1
pattern(s) tried: ['blog/delete\-tag/$']
I don't understand where is the error in my code. Someone can tell me where is the error?

The error is coming because you haven't added angle brackets to capture your slug while constructing your URL. I assume your URL looks like this url(r'blog/update-tag/$', updateBlogTag(), name='updated_tag') and url(r'blog/delete-tag/$', deleteBlogTag(), name='delete_tag') they should look like this instead url(r'blog/update-tag/<slug:slug_tag>/$', updateBlogTag(), name='updated_tag') and url(r'blog/delete-tag/<slug:slug_tag>/$', deleteBlogTag(), name='delete_tag') reference

Related

Adding search bar function into a django project

I'm trying to add search bar in my application but I don't know how to query a database to gives the things that user's search for. I want when user search for a user in a post or category in a post of model to shows the result that user search for, like YouTube search and facebook search, How can i do this in django to give me what i want ?
this is my model:
class Photo(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.CharField(max_length=30,null=True, blank=False)
image = CloudinaryField(blank=False, null=False)
description = models.TextField(null=True)
date_added = models.DateTimeField(auto_now_add=True)
phone = models.CharField(max_length=12, null=False, blank=False)
price = models.CharField(max_length=30,blank=False)
location = models.CharField(max_length=20, blank=False)
def __str__(self):
return str(self.category)
my search form in dashboard template:
<div class="container">
<div class="row justify-content-center">
<form action="{% url 'search' %}" method="get">
<input class="form-control me-2" type="search" placeholder="Search" aria-
label="Search">
<br>
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
the post card in dashboard template:
<div class="container">
<div class="row justify-content-center">
{% for photo in photos reversed %}
<div class="col-md-4">
<div class="card my-2">
<img class="image-thumbail" src="{{photo.image.url}}" alt="Card image cap">
<div class="card-body">
<h2 style="color: yellowgreen; font-family: Arial, Helvetica, sans-serif;">
{{photo.user.username.upper}}
</h2>
<br>
<h3>{{photo.category}}</h3>
<h4>{{photo.price}}</h4>
</div>
<a href="{% url 'Photo-view' photo.id %}" class="btn btn-warning
btn-sm m-1">Buy Now</a>
</div>
</div>
{% empty %}
<h3>No Files...</h3>
{% endfor %}
</div>
</div>
the dashboard view:
def dashboard(request):
photos = Photo.objects.all()
context = {'photos': photos}
return render(request, 'dashboard.html', {'photos': photos} )
the search bar view:
def search(request):
return render(request, 'search.html')
urls:
path('', views.dashboard, name='dashboard'),
path('search/', views.search, name='search')
You can make it using filter method inside your view. Something like:
def dashboard(request):
photos_filter = request.GET.get('filtered[]', False)
photos = Photo.objects.all()
if photos_filter:
photos_filter = eval(photos_filter)
if photos_filter['id'] == 'category':
payments = payments.filter(
category__icontains=payments_filter['value'])
if photos_filter['id'] == 'user':
payments = payments.filter(
user__id=payments_filter['value'])
context = {'photos': photos}
return render(request, 'dashboard.html', {'photos': photos} )
And so on, you can add any filter you like. And in your URL you just add
/?filtered[]=%7B%22id%22:%22category%22,%22value%22:%22Nature%22%7D
Your code will see this filter like a dict obj: {'id': 'category', 'value': 'Nature'}. So after it, you'll get all photos with the category nature

How do I open my edit complaint page for one specific complaint in django

I have a view complaints page where a user can view the complaints he/she have submitted. When the user clicks on one of the cards, I need a new page to open where the user can view the details of that complaint and edit it as well.
It should go from here:
to here: Where they can view details and make changes as well:
This is my models.py:
class Complaint(models.Model):
user = models.ForeignKey(User, on_delete= models.CASCADE, null = True, blank=True)
id = models.AutoField(blank=False, primary_key=True)
reportnumber = models.CharField(max_length=500 ,null = True, blank= False)
eventdate = models.DateField(null=True, blank=False)
event_type = models.CharField(max_length=300, null=True, blank=True)
device_problem = models.CharField(max_length=300, null=True, blank=True)
manufacturer = models.CharField(max_length=300, null=True, blank=True)
product_code = models.CharField(max_length=300, null=True, blank=True)
brand_name = models.CharField(max_length = 300, null=True, blank=True)
exemption = models.CharField(max_length=300, null=True, blank=True)
patient_problem = models.CharField(max_length=500, null=True, blank=True)
event_text = models.TextField(null=True, blank= True)
document = models.FileField(upload_to='static/documents', blank=True, null=True)
def __str__(self):
return self.reportnumber
views.py:
def EditComplaints(request):
complaint = request.user.complaint
form = ComplaintForm(instance=complaint)
if request.method == 'POST':
form = ComplaintForm(request.POST, request.FILES, instance=complaint)
if form.is_valid():
form.save()
context = {'form': form}
return render(request, 'newcomplaint.html', context)
template (the view history page):
<div class="col right-pro-con">
<div class="img-cir">
<form method='POST' action="" enctype="multipart/form-data">
{% csrf_token %} {% if request.user.profile.profile_pic.url %}
<img src={{request.user.profile.profile_pic.url}} alt="" width="100px" height="100px" class="pro-img"> {% else %}
<img src="{% static 'profileimages/msi.jpg' %}" alt="" width="100px" height="100px" class="pro-img"> {% endif %}
<p class="my-name">{{request.user.profile.first}}
<p>
<p class="my-email-id">{{request.user.profile.email}}</p>
</form>
</div>
CONTACT US
</div>
template(edit complaint page):
<div class="col-lg middle middle-complaint-con">
<i class="fas fa-folder-open fa-4x comp-folder-icon"></i>
<h1 class="all-comp">New Complaint</h1>
<form class="" action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<p class="sub-typ-wr">Submit Type</p>
<button type="button" class="btn btn-secondary document-btn">Document</button>
<div class="rep-num">
<label class="written-label" for="">Report Number</label>
<div class="written-txt-field">{{form.reportnumber}}</div>
</div>
<div class="eve-dte">
<label class="written-label" for="">Event Date</label>
<div class="written-txt-field">{{form.eventdate}}</div>
</div>
<div class="eve-typ">
<label class="written-label" for="">Event Type</label>
<div class="written-txt-field">{{form.event_type}}</div>
</div>
<div class="dev-pro">
<label class="written-label" for="">Device Problem</label>
<div class="written-txt-field">{{form.device_problem}}</div>
</div>
<label class="written-label eve-txt" for="">Event Text</label>
<div class="Manufacturer">
<label class="written-label" for="">Manufacturer</label>
<div class="written-txt-field">{{form.manufacturer}}</div>
</div>
<div class="pro-code">
<label class="written-label" for="">Product Code</label>
<div class="written-txt-field">{{form.product_code}}</div>
</div>
<div class="brand-name">
<label class="written-label" for="">Brand Name</label>
<div class="written-txt-field">{{form.brand_name}}</div>
</div>
<div class="exem">
<label class="written-label" for="">Exemption</label>
<div class="written-txt-field">{{form.exemption}}</div>
</div>
<div class="pat-pro">
<label class="written-label" for="">Patient Problem</label>
<div class="written-txt-field">{{form.patient_problem}}</div>
</div>
<div class="comp-textarea">{{form.event_text}}</div>
<button type="button" class="btn btn-secondary attach-btn-1"><div class="fas fa-file-upload">{{form.document}}</div></button>
<button type="submit" name="submit" class="btn btn-secondary save-btn-1"><i class="fas fa-save"></i> Save</button>
</form>
</div>
url:
urlpatterns = [
path('admin/', admin.site.urls),
path('Home/', landing_page.views1.landing, name= 'Home'),
path('Registration/', accounts.views.RegisterPage),
path('Login/', accounts.views.LoginPage, name='Login'),
path('Login/Profile/', accounts.views.profile, name='Profile'),
path('Logout/', accounts.views.LogoutUser, name='Logout'),
path('Login/Add-Complaint/', accounts.views.NewComplaint, name = 'New'),
path('Login/Add-Complaint/Document-Style/', accounts.views.DocComplaint, name='doc'),
path('My-History/', accounts.views.History, name='MyHistory'),
path('Complaint/', accounts.views.EditComplaints, name='Complaint')
]
How do I do this? What should I add in the code for the code to open that particular complaints details and for that complaints page to edit?
okay, so you already have a view. What you need is some sort of unique identifier to help you figure out the actual object that the user wants to edit.
So, in your urls.py you will have to add a pattern similar to:
urlpatterns = [
...
path('complain/<int:pk>/edit/', views.EditComplaint.as_view(), name='edit-complain'),
...
]
Inside your views.py, handle it in a manner something similar to:
from django.views.generics import UpdateView
from django.contrib.auth.mixins import UserPassesTestMixin
from django.http import Http404
from django.utils.translation import gettext_lazy as _
from .models import Complaint
class EditComplaint(UserPassesTestMixin, UpdateView):
model = Complaint
fields = ('info', ) # define whatever field that you want to render
def form_valid(self, form):
# do your form validation here
def test_func(self):
"""ensuring the reporter themselves is updating the complain"""
complain = self.get_object()
if self.request.user == complain.user:
return True
raise Http404(_('This complain does not exist'))
def success_url(self):
# this is only required if your model doesn't have a `get_absolute_url` method
# return the actual url of the instance
All you need now is to add a link inside your template for the EditComplaint view(assuming you already have the list of donations inside your list template as donations).
Something along the lines should do the job
{% for complaint in complaints %}
Edit Complaint
{% endfor %}

The NoReverseMatch error in Django updateView

I am writing and Update View for a model that I have created. The model is a Product Backlog Item. The UpdateView is unable to find a reverse match for my view.
The NoReverseMatch error is saying that Django cannot find a matching url pattern.
My code as below:
UpdatePBI View
class updatePBI(LoginRequiredMixin, UpdateView):
pk_url_kwarg = 'pbipk'
kwargs={'pk_url_kwarg': 'pbipk'}
model = PBI
fields = ['priority', 'summary', 'story_points', 'effort_hours']
login_url = '/accounts/login'
redirect_field_name = '/home'
template_name = 'backtrack/PBIdetail.html'
def dispatch(self, request, *args, **kwargs):
print(kwargs)
return super().dispatch(request, *args, **kwargs)
def get_success_url(self):
return "{}?all=0".format(reverse('pb', kwargs={'pk': self.kwargs['pk']}))
def get_object(self, queryset=None):
obj = get_object_or_404(self.model,pk=self.kwargs['pbipk'])
return obj
def form_valid(self, form):
PBIList = getPBIfromProj(self.kwargs['pk'], '0')
remove = []
priorityData = form.cleaned_data['priority']
if int(priorityData) < self.object.priority:
# Remove all PBI with priority higher than post data priority
# and lesser or equal than current PBI priority
for PBIObj in PBIList:
if PBIObj.priority < int(priorityData) or PBIObj.priority >= self.object.priority:
remove.append(PBIObj.priority)
PBIList = [
PBIObj for PBIObj in PBIList if PBIObj.priority not in remove]
# Increase each objects priority by one
for PBIObj in PBIList:
PBIObj.priority += 1
PBIObj.save()
else:
# Remove all PBI with priority higher than post PBI priority
# and lesser than and equal to Post data priority
for PBIObj in PBIList:
if PBIObj.priority <= self.object.priority or PBIObj.priority > int(priorityData):
remove.append(PBIObj.priority)
PBIList = [
PBIObj for PBIObj in PBIList if PBIObj.priority not in remove]
# Decrease each objects priority by one
for PBIObj in PBIList:
PBIObj.priority -= 1
PBIObj.save()
return super().form_valid(form)
model.py
from django.urls import reverse
# Create your models here.
class PBI(models.Model):
status = models.CharField(max_length=1,
choices=[("N", "Not Done"), ("P", "In Progress"), ("D", "Done")], default="N")
story_points = models.FloatField()
effort_hours = models.FloatField()
summary = models.TextField(default = None)
priority = models.IntegerField(default=0)
Project = models.ForeignKey('Project', on_delete=models.CASCADE, related_name='pbi')
def __str__(self):
return self.summary
class Meta:
db_table = "PBI"
verbose_name = 'PBI'
verbose_name_plural = 'PBIs'
class Project(models.Model):
name = models.CharField(max_length=256)
def __str__(self):
return self.name
class Meta:
db_table = "Project"
urls.py
from django.conf.urls import url
from backtrack import views
from django.shortcuts import redirect
urlpatterns = [
path('', lambda x: redirect('1/'),name='home'),
path('<int:pk>/', views.HomeView.as_view(),name = 'home-project'),
path('<int:pk>/pb/', views.ProductBacklogView.as_view(),name='pb'),
path('<int:pk>/pb/add/', views.AddPBI.as_view(),name='add'),
path('<int:pk>/pb/<int:pbipk>/update', views.updatePBI.as_view(),name='detail'),
path('<int:pk>/pb/<int:pbipk>/delete', views.DeletePBI.as_view(),name='delete')
]
Product Backlog Page
{% block content %}
<h1 class="page-header"><i class="fa fa-file"></i> Product BackLog</h1>
<div class="row placeholders"></div>
{% if data|length == 0 %}
<h4>There are no PBIs</h4>
{% endif %}
<h2 class="sub-header">
<div class="dropdown">
<button class="btn btn-light dropdown-toggle pull-left" type="button" data-toggle="dropdown" style="margin-bottom: 10px;">Filter By
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li>Priority</li>
<li>Story Points</li>
<li>Effort Hours</li>
</ul>
<div class="btn-group btn-toggle">
<button class="btn btn-xs btn-primary active toggle">NOT DONE</button>
<button class="btn btn-xs btn-default toggle">ALL</button>
</div>
<button type="button" class="btn btn-light" style="margin-bottom: 10px;"><i class="fa fa-plus" id="A"></i>ADD</button>
<button type="button" class="btn btn-light" style="margin-bottom: 10px;"><i class="fa fa-times" id="A"></i>DELETE</button>
</div>
</h2>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th> </th>
<th>Priority</th>
<th>Summary</th>
<th>Status</th>
<th>Story Points</th>
<th>Cumulative Story Points</th>
<th>Effort hours</th>
<th>Cumulative Effort hours</th>
</tr>
</thead>
<tbody>
{% for PBI in data %}
<tr>
<td><input type="checkbox"></td>
<td>
{% if PBI.status == "N" %}
{{PBI.priority}}
{% else %}
--
{% endif %}
</td>
<td><a style="text-decoration: none; color: cornflowerblue;" href={% url 'detail' pk=1 pbipk=PBI.id %}>{{PBI.summary}}</a></td>
<td>
{% if PBI.status == "N" %}
Not Done
{% elif PBI.status == "P" %}
In Progress
{% else %}
Done
{% endif %}
</td>
<td>{{PBI.story_points}}</td>
<td>{{PBI.sum_story_points}}</td>
<td>{{PBI.effort_hours}}</td>
<td>{{PBI.sum_effort_hours}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<script>
$.urlParam = function (name) {
var results = new RegExp('[\?&]' + name + '=([^&#]*)')
.exec(window.location.search);
return (results !== null) ? results[1] || 0 : false;
}
$(document).ready(function () {
if($.urlParam('all') == '1'){
$(this).find('.toggle').toggleClass('active');
if ($(this).find('.btn-primary').length>0) {
$(this).find('.toggle').toggleClass('btn-primary');
}
}
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host + getUrl.pathname;
$('.btn-toggle').click(function(){
console.log($.urlParam('all') == '0')
if($.urlParam('all') == '0')
window.location.replace(baseUrl + "?all=1");
else
window.location.replace(baseUrl + "?all=0");
})
});
</script>
{% endblock content %}
I am getting this error
NoReverseMatch at /home/1/pb/50/update
Reverse for 'detail' with keyword arguments '{'pk': 1, 'pbipk': ''}' not found. 1 pattern(s) tried: ['home/(?P<pk>[0-9]+)/pb/(?P<pbipk>[0-9]+)/update$']
Update
I have found that the error is because I am setting the form action with the PBI.id but the Update view is not passing a PBI to my template. How do I fix this?
Okay. I found what I was doing wrong. I have to override the get_context_data() function of the template view mixin and pass the PBI in the context after calling super().get_context_data(form).

When refering to the object pk in the tableview i get a pk error but i still can refere to the object from the context

I have a django app where I want to show a table of user entries and users can delete/edit entries from the table by buttons. I used django-tables2 as the library to render the table.
Tables.py
class PatientTable(tables.Table):
FirstName = tables.Column(linkify=("patients:patient_detail", {"pk": tables.A("pk")}))
LastName = tables.Column(linkify=("patients:patient_detail", {"pk": tables.A("pk")}))
Telephone_no = tables.Column(linkify=("patients:patient_detail", {"pk": tables.A("pk")}))
delete = TemplateColumn('<button type ="button" class ="btn btn-danger" data-toggle="modal" data-target="#modalDelete" >Deleta</button>',extra_context={'patient': 'Patient'})
class Meta:
model = Patient
attrs = {'class': 'table table-striped table-hover'}
exclude = ("user", "Notes", "Adress")
template_name = 'django_tables2/bootstrap4.html'
Views.py
def Patients_list(request):
patients = Patient.objects.all()
table = PatientTable(patients.filter(user=request.user))
RequestConfig(request).configure(table)
return render(request, 'patients/patients_list.html',{
'table' : table,
'patients':patients,
})
here in the views I defined the patients in the context to be callable in the template,It's callable but i can't call the patients.pk, it always return a value error.
Template
{% extends 'base.html' %}
{% load render_table from django_tables2 %}
{% block content %}
<div id="content">
{% if user.is_authenticated %}
<h1> Patients list: </h1>
<br>
Add Patient
<br>
<br>
{% render_table table %}
{% else %}
<h2>please login</h2>
{% endif %}
</div>
<div class="modal fade" id="modalDelete" tabindex="-1" role="dialog" aria-labelledby="modalDelete"
aria-hidden="true">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Delete patient!</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete this patient?</p>
</div>
<div class="modal-footer">
<form method="POST" action="{% url 'patients:patient_delete' pk=patients.pk %}">
{% csrf_token %}
<input class="btn btn-danger" value="Yes" type="submit" >
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
in this template I get this error :
Reverse for 'patient_delete' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['patients/delete/(?P<pk>[0-9]+)$']
I tried
Patients.pk
pk
but it didn't work,in the template i tried making a for loop(after deleting the form ofc) to show each patient First name in a paragraph tag and it worked I also tried making a different template having for the delete form and it worked but now i want to make the delete form in a modal callable by the button.
My model:
# Patient model each patient is uniquely identified by his doctor/user
class Patient(models.Model):
FirstName = models.CharField(max_length=264)
LastName = models.CharField(max_length=264)
Adress = models.TextField(blank=True, null=True)
Telephone_no = PhoneNumberField(blank=True, null=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,related_name='patients')
birth_date = models.DateField()
# Age = models.CharField(max_length=100,blank = True ,null = True)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
Notes = models.TextField(blank=True, null=True)
def __str__(self):
return str(self.FirstName) + " " + str(self.LastName)
def get_absolute_url(self):
return reverse('patient_detail', kwargs={"pk": self.pk})
There's another related model to this one has a patient field as a ForiegnKey btw.
I tried changing the view into this as user from recommended but it's the same problem
the new view:
def Patients_list(request):
patients = Patient.objects.filter(user=request.user)
table = PatientTable(patients)
RequestConfig(request).configure(table)
return render(request, 'patients/patients_list.html',{
'table' : table,
'patients':patients,
})
The suggestion was that I couldn't get the pk from Patient.objects.all() and I needed to change it to a form with get but get didn't work so i used filter.
I think if i changed it to a CBV it should work but I don't really know how to make the queryset should i make it with defining it just like the normal CBV.
I've been stuck on this for 10 days now asking on many forums/sites so I really appreciate any help.
The only way to achieve what i wanted is to render the table manually in the template by making a for loop and iterate through all objects.

How get multiple BooleanFields in a form using Django

I have a form in my site to get a report about some "collective payment". It has 3 main field: Value, date of payment and who paid.
The field "who paid" is a table containing the name of all users and a checkbox.
Currently I'm looping over all users, adding their full names to the table with a single checkbox. But I don't know how to get this data in my form associating it with each user name (just the text).
How can I get multiple BooleanFields in my form ? Is there a way of associate each BooleanField with an user's name?
model.py
from django.db import models
#created_date attibute needs it
from django.utils import timezone
# This Model is a super class "Financial Transaction"
class GroupTransaction(models.Model):
name = models.CharField(max_length=257, default='')
who_paid = models.CharField(max_length=257, default='')
value = models.DecimalField(max_digits=6, decimal_places=2)
justification = models.CharField(max_length=257, default='')
created_date = models.DateTimeField(default=timezone.now)
date = models.CharField(max_length=257, default='')
receipt = models.FileField(upload_to='comprovantes', blank=True, null=True)
its_type = models.CharField(max_length=257, default='')
def __str__(self):
#INCOMPLETOreturn "%s fez a movimentação financeira de %d para %s no dia " % (self.name, self.restaurant)
return "%s - %s" % (self.name , self.who_paid)
view.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect
from deposit.forms import DepositForm,MonthlyDepositForm
from django.contrib.auth.models import User
# Create your views here.
#login_required
def deposito(request):
if request.method == 'POST':
form = DepositForm(request.POST, request.FILES)
if form.is_valid():
form.save()
HttpResponseRedirect('/historico/')
else:
print (str(form.errors.as_data()))
else:
form = DepositForm()
groupForm = MonthlyDepositForm()
return render(request, 'shell/app_shell.html', {
'is_deposit' : True,
'title' : 'Deposit',
'transaction' : form,
'groupTransaction' : groupForm,
'users': User.objects.all()
})
form.py
class MonthlyDepositForm(forms.ModelForm):
value = forms.DecimalField()
date = forms.CharField(widget=forms.TextInput(attrs={
'class':'datepicker picker__input',
'readonly':'',
'tabindex':'54',
'aria-haspopup':'True',
'aria-expanded':'false',
'aria-readonly':'false',
'aria-owns':'birthdate_root'
}))
who_paid = forms.BooleanField()
its_type = forms.CharField(widget=forms.HiddenInput(attrs={'readonly':True}),
initial='Deposito Mensal')
class Meta:
model = GroupTransaction
fields = ('value', 'date','who_paid','its_type')
template.html:
<form class="col s12">
{% csrf_token %}
{{ groupTransaction.its_type }}
<div class="row"></div>
<!-- Nome do evento -->
<div class="row">
<div class="input-field col s6">
<!-- <input id="nome_evento" type="number" value="10" step="any" min="0.05" max="400" class="validate" required> -->
{{ groupTransaction.value }}
<label for="nome_evento">Value</label>
</div>
<div class="input-field col s6">
<!-- <input type="text" class="datepicker picker__input" readonly="" tabindex="54" aria-haspopup="true" aria-expanded="false" aria-readonly="false" aria-owns="birthdate_root" required> -->
{{ groupTransaction.date }}
<label for="data-mensal" data-error="Data inválida">Date</label>
</div>
</div>
<!-- Petianos que irão para o evento -->
<table class="striped">
<thead>
<!-- Cabeçalho tabela -->
<tr>
<th>Who Paid</th>
<th>
<div class="switch">
<b class="center-align">Default</b>
<label>
<input type="checkbox">
<span class="lever"></span>
</label>
</div>
</th>
</tr>
<!-- ============= -->
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.get_full_name }}</td>
<td>
<div class="switch">
<label>
<!-- <input type="checkbox"> -->
{{ groupTransaction.who_paid }}
<span class="lever"></span>
</label>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row"></div>
<div class="row"></div>
<!-- Botão de registrar saque (submit) -->
<div class="row">
<button class="btn waves-effect waves-light col s6 m3 offset-s6 offset-m9 blue" type="submit" name="action">Submit
<i class="material-icons right">send</i>
</button>
</div>
</form>
How the form is:
You need to make who_paid a ManyToManyField(User). Then in the form you can set its widget like this:
class Meta:
model = GroupTransaction
fields = ('value', 'date','who_paid','its_type')
widgets = {
'who_paid': forms.CheckboxSelectMultiple(),
}
That will give you the right structure. Then you can render it manually if you want to change the display.