Django display content based on dropdown select - django

I am new in Django.
I want to display content based on dropdown selection.
In this example i want to show all the workshops data from the location selected in the dropdown.
Is it possible to achieve that without reloading the page? or if it must reload the page, is it possible to stay on current view after reloading the page?
Thank you.
I have tried to use post method and use onChange attribute on my forms.
It successfully reload the page but the workshops content is not shown, the dropdown selection go back to default '--- Choose your location ---' and the page go back to the top.
Below is the code of the forms
class LocationForm(forms.Form):
location = forms.ModelChoiceField(label='', queryset=Location.objects.all(), empty_label="--- Choose your location ---",
widget=forms.Select(
attrs={'id': 'ddlLocation', 'name':'ddlLocation', 'class':'selectpicker', 'data-live-search':'true', 'data-size':'5', 'onChange':'frLocation.submit();' }
)
)
Below is the code of the class
class HomeView2(ListView):
template_name = 'myapp/index.html'
def get(self, request):
form_location = LocationForm()
location_id = request.GET.get('location_id')
workshops = Workshop.objects.filter(location_id=location_id).order_by('workshop_name')
args = {'form_location':form_location, 'workshops':workshops}
return render(request, self.template_name, args)
def post(self,request):
form_location = LocationForm()
location_id = request.GET.get('location_id')
workshops = Workshop.objects.filter(location_id=location_id).order_by('workshop_name')
args = {'form_location':form_location, 'workshops':workshops}
return render(request, self.template_name, args)
and in index.html
<section class="page-section" id="services">
<div class="container">
<h2 class="text-center mt-0">At Your Service</h2>
<hr class="divider my-4">
<div class="row justify-content-center">
<div class="col-lg-3 col-md-6 text-center">
<div class="mt-5">
<i class="fas fa-4x fa-wrench text-primary mb-4"></i>
<h3 class="h4 mb-2">Select location</h3>
<form id="frLocation" name="frLocation" method="POST">
{% csrf_token %}
{{form_location}}
</form>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-lg-3 col-md-6 text-center">
<div class="mt-5">
<form id="frWorkshop">
{% for workshop in workshops %}
<p>Workshop: {{workshop.workshop_name}}</p>
{% endfor %}
</form>
</div>
</div>
</div>
</div>
</section>

Related

django show pagination links First , Previous , Next , Last on edit page that uses UpdateView or DetailView

I am using django 3.2 along with datatables and bootstrap 5. it shows pagination correctly using datatables. I want to show Links/buttons like First, previous,Next and Last on edit productstatus form using datatables pagination or django pagination django.core.paginator whose details as shown below
class ProductStatus(models.Model):
ProductID = models.CharField(max_length=512, verbose_name="ProductID", null=False, blank=False)
Description = models.CharField(max_length=512, verbose_name="Description", null=True, blank=True)
CreateDate = models.DateTimeField(verbose_name=_("CreateDate"), blank=True)
modificationtime = models.DateTimeField(verbose_name="modificationtime", null=True, blank=True, )
...
def __str__(self):
return self.ProductID
def get_absolute_url(self):
return reverse('productdetail', args=[str(self.id)])
urls.py has entry as shown below
path('editproduct/int:pk/edit/', EditProductView.as_view(), name='editproduct'),
views.py contains following code
class EditProductView(LoginRequiredMixin, UpdateView):
model = ProductStatus
template_name = 'editproduct.html'
form_class = EditProductStatusForm
login_url = 'login'
def form_valid(self, form):
editedproduct = form.save(commit=False)
editedproduct.modificationtime = timezone.now()
editedproduct.save()
# self.object = editedproduct
return super().form_valid(form)
Forms.py contains
class EditProductStatusForm(forms.ModelForm):
class Meta:
model = ProductStatus
editproduct.html looks as shown below
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<br>
<!-- show 4 links in bootstrap navigation bar -->
<nav class="navbar navbar-expand-lg navbar-light">
<div class="container-fluid ">
<div class="nav navbar-left">
<ul class="nav navbar-nav">
<li><a class="btn btn-info btn-sm" style="padding-left:0px;margin-left:10px" href="#" role="button">« First</a></li>
<li><a class="btn btn-info btn-sm" style="padding-left:0px;margin-left:10px" href="#" role="button">‹ Previous</a></li>
</ul>
</div>
<div class="nav navbar-right">
<ul class="nav navbar-nav">
<li> <a class="btn btn-info btn-sm" style="padding-left:0px;margin-left:10px" href="#" role="button">Next ›</a></li>
<li> <a class="btn btn-info btn-sm" style="padding-left:0px;margin-left:10px" href="#" role="button">Last »</a></li>
</ul>
</div>
</div>
</nav>
<h3 class="text-center">Change Product Status </h3>
<form class="form-inline" role="form">
<div class="row">
<div class="col">
<div class="input-group mb-3">
<span class="input-group-text" style="background-color: #ffffff" id="labelFor-Product ID">Product ID </span>
<input type="text" style="background-color: #ffffff" class="form-control" value="{{ object.ProductID }}" readonly>
</div>
</div>
</form>
<form method="post">
{% csrf_token %}
<div class="row">
<div class="col-6">
{{ form.Description| as_crispy_field }}
</div>
</div>
<br>
<button type="submit" class="btn btn-success">Save</button>
</form>
{% endblock content %}
editproduct url is invoked from other datatables using list page as . this page allows sorting by click on table header
I need to show pagination on editproduct page with 4 links/buttons First,Previous,Next and Last or datatables like pagination so that user dont have go back to product list page and then click on edit icon to open editproduct status page and user can go to first product, Previous product, next product or last product from edit product status page itself.
I am aware of datatables pagination that requires passing productstatus_list and using table but not sure how to use datatables pagination or django.core.paginator on this editproduct status page or on product details page that uses DetailView where only product id is passed and available as shown above. what change/update is needed in above code to show desired pagination on the edit productstatus page.

The 'file' attribute has no file associated with it

when I add a video from addvideo templates file its say: The 'file' attribute has no file associated with it. I want a user to be able to upload video.
when I add videos from my admin it's working fine, but when I added it from my form page its added the video in admin but its does not show the video in the home page and it's highlight my video tag src="{{video.file.url}}" saying: 'file' attribute has no file associated with it.
this is my models:
class Video(models.Model):
file = models.FileField(upload_to='file', null=False, blank=False)
this is my views:
def addvideo(request):
if request.method == 'POST':
file = request.FILES.get('video')
videos = Video.objects.create(
file=file
)
return redirect('home')
return render(request, 'addvideo.html')
def home(request):
videos = Video.objects.all()
return render(request, 'home.html', {'videos': videos})
this is my addvideo templates:
<div class="col-md-5">
<form action="" method="POST">
{% csrf_token %}
<div class="card">
<div class="form-group m-3">
<label>Upload Your Video</label><br><br>
<input required name="video" type="file" class="form-control-file">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</div>
</form>
</div>
this is my home templates:
<div class="container">
{% for video in videos %}
<div class="row justify-content-center">
<video style="height: 500px; width: 500px;" controls src="{{video.file.url}}">
</video>
</div>
{% endfor %}
</div>
In order to submit a file with a HTML form, you need to specify how it will send the file content: you need to specify the enctype="…" [MozillaDev]. You can do this with:
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="card">
<div class="form-group m-3">
<label>Upload Your Video</label><br><br>
<input required name="video" type="file" class="form-control-file">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</div>
</form>

For Loop Populate ID In URL Django

I have a button on my template that says check progress, what the button does is takes you to another page for that user based on their user id.
/points/student_progress/1000 <-- id
What I'm trying to accomplish:
When my for loop runs to populate the student names on my template, i want it also to populate the student ID on the button as well. /points/student_progress/{{student_id}} . Here is my code. How do i add this in ?
Views.py
#login_required
def K8_Points_Classroom(request):
#context_from_k8_points = request.session['k8_points_context']
if request.method == 'POST':
form = K8Points_ClassroomForm(request.POST)
if form.is_valid():
form.save(commit=False)
form.save()
class_name = form.cleaned_data.get('class_name')
getstudents = Student.objects.filter(class_name = class_name)
students = getstudents.all()
form = K8Points_ClassroomForm()
context = {'form': form ,'students' : students, 'class_name': class_name,}
messages.success(request,("Points were successfully added for student !"))
return render(request, 'points/k8_points_classroom.html', context )
if not form.is_valid():
messages.warning(request,(form._errors))
class_name = request.POST.get('class_name')[0]
getstudents = Student.objects.filter(class_name = class_name)
students = getstudents.all()
context = {'form': form, 'students': students,}
return render(request, 'points/k8_points_classroom.html', context )
else:
form = K8Points_ClassroomForm()
return render(request, 'points/k8_points_classroom.html', context)
#login_required
def K8_Points(request):
if request.method == 'POST':
form = K8PointsForm(request.POST)
if form.is_valid():
form.save(commit=False)
class_name = form.cleaned_data.get('class_name')
getstudents = Student.objects.filter(class_name = class_name)
students = getstudents.all()
form = K8Points_ClassroomForm()
context = {'form': form ,'students' : students, 'class_name': class_name,}
# request.session['k8_points_context'] = context
return render(request,'points/k8_points_classroom.html', context)
else:
return HttpResponseBadRequest("Bad Request")
else:
form = K8PointsForm()
return render(request, 'points/k8_points.html', {'form': form} )
def Student_Progress(request, studentpsid):
studentid = Student.objects.get(studentpsid=studentpsid)
if K8Points.objects.filter(student_name=studentpsid).exists():
return render(request, 'points/student_progress.html', {'studentid': studentid} )
else:
return HttpResponseBadRequest("Student doesn't exist !")
HTML Template
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% crispy K8Points_ClassroomForm %}
{% load static %}
{% block content %}
<br>
<h2>{% load static %}
<img src="{% static 'forms/star.png' %}" alt="chain" height="62" width="62"> {{class_name}}</h2>
<br>
<br>
<script> </script>
<form action="/points/k8_points_classroom" method="POST">
{% csrf_token %}
<!-- Start Date -->
<div class="container">
<div class="container">
<div class='row'>
<div class="col-4">
<p> Recording Data as User : {{user.username}} </p>
</div>
</div>
<div class='row'>
<div class = "col-2">
<input type="button" onclick="window.location.href = '/points/k8_points';" value="Exit Classroom"/>
</div>
</div>
<br>
<div class='row'>
<div class = "col-2">
{{form.date|as_crispy_field }}
</div>
<div class = "col-2">
{{form.week_of|as_crispy_field }}
</div>
<div class = "col-2">
{{form.day|as_crispy_field }}
</div>
</div>
</div>
</form>
<div class="jumbotron" align="middle">
<img src="{% static 'forms/levelup.png' %}" alt="levelup" height="120" width= "120">
<h1>My Students</h1>
<!-- Line Break -->
<hr style="border: 1px solid black;"/>
<!-- Line Break -->
<div class="row mb-3">
{% for i in students%}
<div class="col-md-4 themed-grid-col"><h2>{{i.student_name}}</h2>
<p align="left"> Today's Score: {{total}}</p>
<h4>
<button type="button" class="btn btn-primary " data-toggle="modal"
data-target="#PointsBox{{student.pk}}"><i class="fas fa-level-up-alt"></i> Level Up
</button>
<i class="fas fa-chart-line"></i> Check Progress
</h4>
<div id="PointsBox{{student.pk}}" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<img src="{% static 'forms/star.png' %}" align="left" alt="chain" height="42"
width="42">
<h4 class="modal-title">Points Confirmation </h4>
<button type="button" class="close" data-dismiss="modal"> ×</button>
</div>
<div class="modal-body">
<h6>
<div class="modal-body">Please add the selected points for the current
student.</div>
</h6>
<form action="/points/k8_points_classroom" method="POST">
{% csrf_token %}
<div class="form-row" align='left'>
<div class="col-7">
{{form.class_name|as_crispy_field }}
{{form.student_name|as_crispy_field }}
{{form.time_frame|as_crispy_field }}
</div>
</div>
<div class="form-row">
<div class="col-3" align='left'>
{{form.behavior|as_crispy_field }}
{{form.academic|as_crispy_field }}
<button type="submit" class="btn btn-success" ><i
class="fas fa-star"></i> Level Up
</button>
</div>
</div>
</div>
<div class="modal-foot"></div>
</div>
</div>
</div>
</div>
</form>
{% endfor %}
<script>
const class_name = "{{class_name}}";
var classnamedropdown = document.getElementById('id_class_name');
for (i = 0; i < classnamedropdown.options.length; i++) {
// if(classnamedropdown.options[i].text == "Mr. Neo 8th Grade Science")
if(classnamedropdown.options[i].text == class_name)
{
console.log(classnamedropdown.options[i].text)
$("#id_class_name").val(classnamedropdown.options[i].value)
}
}
</script>
{% endblock %}
Check Progress
Had to just add the {{i.studentpsid}} in the loop.

Django search bar not getting to the right page

My page has two ways to search services - one is a search bar and the other is clickable categories. The clickable category go to a page that has a category primary key attached to the view and the search bar results do not have a category pk attached. Thus, I created two separate views for this reason. The problem is that both views go to the same page the index.html. I want the search bar to go to the index_search.html. I think I set-up everything correctly, but it still does not work.
Two views: search view, clickable items view:
#search form view
def service_finder(request):
model = Service
if ('s' in request.GET) and request.GET['s'].strip():
query_string = request.GET['s']
#get query is just searching for search terms in those fields of the query set
entry_query = get_query(query_string,['description', 'tags', 'category'])
table = Service.objects.filter(entry_query)[:60]
return render(request, 'index_search.html', {'table': table})
#clickable items view
def servicesListView(request, category):
model = Service
table = Service.objects.filter(category=category)[:60]
return render(request, 'index.html', {'table': table})
Here is the html template with both the search bar and clickable items:
{% block content %}
<main class="category">
{% include "search_form.html" %}
<section class="category-list">
<div class="container">
<div class="row">
{% for service in service_cat %}
<div class="col-sm-12 col-lg-6">
<a
href="{% url 'services_list' service.category %}"
{{ service.category }}
</a>
</div>
{% endfor %}
</div>
</div>
</section>
</main>
{% endblock %}
Here is the search bar file or search_form.html:
<div class="search-bar">
<div class="container">
<form method="get" action="{% url 'service_finder' %}">
{% csrf_token %}
<div class="input-group">
<input name='s' value="{{request.GET.s}}" type="text" class="form-control" placeholder="Search services" aria-label="Search" aria-describedby="search">
<div class="input-group-append">
<button class="btn btn-secondary" type="submit" id="button-addon2">Go</button>
</div>
</div>
</form>
</div>
</div>
Here is the urls for the two pages:
path('services/<category>/', views.servicesListView, name='services_list'),
path('services/find/', views.service_finder, name='service_finder'),
SOLVED:
Fixed this by switching the order of the urls.
It's because the path /services/find/ matches the previous pattern /services/<category>/. Just explaining the reason why the fix worked!

Django Bootstrap form field won't resize

I am using bootstrap to display my django forms but am having trouble getting them to resize. One of the forms is a text input area and I want it to span most of my panel width. I've tried multiple things but haven't been able to resize it/make the input area bigger.
The html:
<div class="container-fluid">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="text-center">
Raw sQL Query
</h4>
</div>
<form action="/InterfaceApp/table_search/" method="post" class="form">
{% csrf_token %}
<div class="panel-body text-center">
{% bootstrap_form rawsQL %}
</br>
<div class="container-fluid">
<button type="submit" class="btn btn-primary center-block" value="Submit" name="rawsQL">
{% bootstrap_icon "fire" %} Submit
</button>
</div>
</div>
</form>
</div>
The form:
class TextFieldForm(forms.Form):
def __init__(self,*args,**kwargs):
section_label = kwargs.pop('section_label')
initial_value = kwargs.pop('initial_value')
required_val = kwargs.pop('required')
super(TextFieldForm,self).__init__(*args,**kwargs)
self.fields['text'].label=mark_safe(section_label)
self.fields['text'].initial=initial_value
self.fields['text'].required=required_val
text = forms.CharField()
Right now it looks like this:
Can anyone help me with making the input area wider??
Have a look at grid system and form control sizing.
So it turns out that when you pass in forms to django templates like {% bootstrap_form formname %} you have to go into where you defined the form to edit how it looks. I fixed my resizing issue by doing:
Form:
class TextFieldForm(forms.Form):
def __init__(self,*args,**kwargs):
section_label = kwargs.pop('section_label')
initial_value = kwargs.pop('initial_value')
required_val = kwargs.pop('required')
super(TextFieldForm,self).__init__(*args,**kwargs)
self.fields['text'].label=mark_safe(section_label)
self.fields['text'].initial=initial_value
self.fields['text'].required=required_val
text = forms.CharField(widget=forms.TextInput(attrs={'class':"form-control text-center",'placeholder':".col-md-8"}))
html:
<div class="col-md-8 centering">
{% bootstrap_form rawsQL %}
</div>