Django - How to get checked objects in template checkboxes? - python

Im new in Django,
I'm using xhtml2pdf for rendering data objects from template to PDF file , and i want to allow users to render only checked objects by checkboxes into pdf, is there anyway to filter that in Django ?
Thanks
views.py :
def render_to_pdf(template_src, context_dict={}):
template = get_template(template_src)
html = template.render(context_dict)
result = BytesIO()
pdf = pisa.pisaDocument(BytesIO(html.encode('ISO-8859-1')), result, link_callback=link_callback)
if pdf.err:
return HttpResponse('Error')
return HttpResponse(result.getvalue(), content_type='application/pdf')
class ViewPDF(View):
#method_decorator(login_required(login_url='livraison:login_page'))
def get(self, request, *args, **kwargs):
checked_objects = [i dont know how to get them]
queryset = Livraison.objects.filter(id__in=[checked_objects]) # i want something does that
data = {
'livraisons' : queryset,
'now' : f'Livraisons-{date.today()}'
}
pdf = render_to_pdf('pdf_template.html', data)
return HttpResponse(pdf, content_type='application/pdf')

use forms to get user data.
class LivraisonSelectForm(forms.Form):
livraison = forms.ModelChoiceField(label='select', queryset=Livraison.objects.all(), widget=forms.CheckboxInput())
then use it in your view:
class ViewPDF(FormView):
form_class = LivraisonSelectForm
template_name = 'path_to_template_with_html_to_filter_data'
#method_decorator(login_required(login_url='livraison:login_page'))
def form_valid(self, form):
checked_objects = form.cleaned_data.get('livraison', [])
queryset = Livraison.objects.filter(id__in=checked_objects) # i want something does that
data = {
'livraisons' : queryset,
'now' : f'Livraisons-{date.today()}'
}
pdf = render_to_pdf('pdf_template.html', data)
return HttpResponse(pdf, content_type='application/pdf')
and don't forget to show this form in your html {{ form }}

**
UPDATE
**
I Found a solution , i used Ajax code to collect every selected object
// check selected objects (#pdf is the id of the button which gonna generate the pdf file)
$('#pdf').click(function () {
var id = [];
$(':checkbox:checked').each(function (i) {
id[i] = $(this).val()
})
if (id.length === 0) {
alert('Please Select something..');
} else {
$.ajax({
url: '.',
method: 'GET',
data: {
id,
},
success: function (response) {
console.log('PDF is ready')
}
})
}
});
then i ad the variable into the view function to collect the selected objects and filter the queryset
myFunction.selected_ones = request.GET.getlist('id[]')
then filter queryset in the generated_pdf_func
queryset = MODEL.objects.filter(id__in=[x for x in myFunction.selected_ones if x != '0'])
NOTE : <if x != '0'> is important in case you want to select all because it returns 0 and you don't have any id = 0 in the DB

Related

Passing data from a form to a view Django

I have two functions in views.py, the first one allows you to display information from tables. The second is to get data from the form and redirect to the page with the result. How can I pass the data received from the form to the first function to display information from the tables based on this very data?
In the first function:
def SuOp(request):
allrooms = Rooms.objects.all()
allfood = Food.objects.all()
alltours = Tours.objects.all()
data = {
'allfood': allfood,
'allrooms': allrooms,
'alltours': alltours,
}
return render(request, './obj.html', data)
in the second function:
def Main(request):
error = ''
if request.method == 'POST':
form = SearchMain(request.POST)
if form.is_valid():
budget = form.cleaned_data.get("budget")
arrival_date = form.cleaned_data.get("arrival_date")
departure_date = form.cleaned_data.get("departure_date")
number_of_people = form.cleaned_data.get("number_of_people")
count_days = (departure_date-arrival_date).days
return redirect('allobject')
else:
error = 'The form has been filled out incorrectly'
form SearchMain()
data = {
'formS': form,
'error': error,
}
return render(request, './main.html', data)
urls.py:
urlpatterns = [
path('', views.Main, name='main'),
path(r'allobject/$', views.SuOp, name='allobject')
]
You can use sessions to pass values from one view to another. First set the session:
if form.is_valid():
budget = form.cleaned_data.get("budget")
request.session['budget'] = budget
...
return redirect('allobject')
Then your other view can get the session variable:
def SuOp(request):
budget = request.session.get('budget')
...
allrooms = Rooms.objects.all()
allfood = Food.objects.all()
alltours = Tours.objects.all()
data = {
'allfood': allfood,
'allrooms': allrooms,
'alltours': alltours,
}
return render(request, './obj.html', data)
The other option is to do all the calculations in the view that receives the budget, arrival_date, departure_date, number_of_people, save the desired results to the Rooms, Food and Tours objects.

django file upload progress bar with XMLHttpRequest

i created a normal django model.ModelForm and it is worked perfectly until i tried to add Progress bar for files uploading, i have an issue. i recieve the form information(request.POST and request.FILES) twice! but it is save the data only once in database, so also it is work, but i know i have a mistake in my code and i want to understand my mistake.
this is my function for displaying the progress bar:
function UploadFilesWithProgress(form, url) {
const progressbarWrap = document.querySelector('.progress-bar-wrap'),
label = progressbarWrap.querySelector('h6'),
percentage = progressbarWrap.querySelector('span'),
progressbarFill = progressbarWrap.querySelector('.progress > .progress-bar')
let xhr = new XMLHttpRequest()
xhr.open('POST', url, true);
xhr.upload.onloadstart = function (e) {
progressbarWrap.classList.remove('d-none')
percentage.textContent = '0%'
label.textContent = 'uploading...'
};
xhr.upload.onprogress = function (e) {
const percent = e.lengthComputable ? (e.loaded / e.total) * 100 : 0;
progressbarFill.style.width = percent.toFixed(2) + '%';
progressbarFill.setAttribute('aria-valuenow', percent.toFixed(2))
percentage.textContent = percent.toFixed(2) + '%';
}
xhr.upload.onloadend = function (e) {
label.textContent = 'uplaod completed!'
percentage.textContent = 'completed!'
}
xhr.send(new FormData(form));
}
Form = document.getElementById('add-course-form')
if (Form) {
Form.onsubmit = function () {
UploadFilesWithProgress(Form, Form.action);
}
}
and this is my view:
# I use CBV, so i share just the post method to not get missy.
def post(self, *args, **kwargs):
form = OfflineTutorialForm(
user=self.request.user.booth,
data=self.request.POST,
files=self.request.FILES
)
video_formset = AddOfflineVideoTutorialFormSet(
data=self.request.POST,
files=self.request.FILES
)
print(self.request.POST, self.request.FILES)
if form.is_valid() and video_formset.is_valid():
off_tutorial = form.save(commit=False)
off_tutorial.booth = self.request.user.booth
off_tutorial.save()
form.save_m2m()
video_off_tutorial = video_formset.save(commit=False)
for video in video_off_tutorial:
video.tutorial = off_tutorial
video.save()
return redirect('offline-tutorial')
return redirect('/')
It looks like you are uploading the data via form submit and ajax, you can prevent the form from submitting normally with event.preventDefault()
Form.onsubmit = function (event) {
event.preventDefault();
UploadFilesWithProgress(Form, Form.action);
}

Using ajax jquery for search form

I'm working on a Django project where I want to use ajax jquery to complete my search in my search form.
Tried everything, but it does not seem to work.
Pls, where have I missed it?
used this tutorial
views.py
import json
def search(request):
if request.method == 'POST':
form = SearchForm(request.POST)
if form.is_valid():
query = form.cleaned_data['query']
catid = form.cleaned_data['catid']
if catid == 0:
products = Product.objects.filter(name__icontains=query)
else:
products = Product.objects.filter(name__icontains=query, category_id=catid)
category = Category.objects.all()
context = {
'products': products,
'category': category,
'query': query,
}
return render(request, 'shop/product/search.html', context)
return HttpResponseRedirect('/')
def search_auto(request):
if request.is_ajax():
q = request.GET.get('term', '')
products = Product.objects.filter(name__icontains=q)
results = []
for pl in products:
product_json = {}
product_json = pl.name
results.append(product_json)
data = json.dumps(results)
else:
data = 'fail'
mimetype = 'application/json'
return HttpResponse(data, mimetype)
<script>
$(function() {$("#query").autocomplete({
url: "{% url 'shop:search_auto' %}",
select: function (event, ui) {AutoCompleteSelectHandler(event, ui)},
minLength: 2,
});
});
function AutoCompleteSelectHandler(event, ui)
{var selectedObj = ui.item;}
</script>
path('search', views.search_auto, name='search_auto'),
Thanks.

Is there any way to access the variable inside a function from another function within the same class in TemplateView of django

$.ajax({
'url' : '{% url 'add_question_main' %}',
'type' : 'GET',
'data' : {
'num' : num
},
'success' : function(data) {
if (data == "success") {
alert('request sent!');
}
}
});
how to access the variable within a function from another function within the same class in django's TemplateView
class add_question_main(TemplateView):
template_name = 'add_question_paper/index.html'
def get(self,request,*args,**kwargs):
form = question_details_form()
no_txt = request.GET.get('num')
return render(request,self.template_name,{'form':form})
def post(self,request,*args,**kwargs):
form = question_details_form(request.POST)
return render(request,self.template_name,{'form':form})
I wonder how could I use the value of no_txt in function post?
because the get function does not get called when
a POST is issued, your best bet is to get that
same value independently by refactoring the call
into a helper method.
Option #1:
def get_no_txt(self):
return self.request.GET.get('num')
def get(self,request,*args,**kwargs):
form = question_details_form()
no_txt = self.get_no_txt()
return render(request,self.template_name,{'form':form})
def post(self,request,*args,**kwargs):
form = question_details_form(request.POST)
no_txt = self.get_no_txt()
return render(request,self.template_name,{'form':form})
Whether this will do what you want it to will also
depend on your template and what data you are submitting
with the form. In particular, your action attribute on your
form should have the num query parameter in it.

Python/Django form where user selects from a list of Images

I'm new to django and want to make a form that allows a user to select one of three images using radio boxes, once the user selects the image it is saved to their profile and displayed on their profile page.
I am using:
django 1.8.3
userena 1.4.1
Any help or links to documentation that will help would be great.
Basic example. Models:
def get_upload(instance, filename):
return "uploaded_files/user_%s_%s_%s" % (instance.user, datetime.datetime.today().strftime("%d-%m-%Y %H-%M-%S"), filename)
class UserModel():
# your fields
image = models.FileField(upload_to=get_upload, default='')
FileField
Forms:
class UploadForm(forms.ModelForm):
"""Auxiliary class to make file uploading more convenient."""
def __init__(self, *args, **kwargs):
super(UploadForm, self).__init__(*args, **kwargs)
class Meta:
model = UserModel
fields = ('image')
View:
def upload(request):
if request.method == "POST":
profile = request.user.profile
image_type = request.POST.get("image_type", None)
if image_type == "blah":
profile.image = request.FILES[image_type]
else:
return HttpResponse("Error")
request.user.profile.save()
return HttpResponse('OK')
request.FILES
JS with soem Jquery:
var SIZE_RESTRICT = 10*1024*1024; //10 Mbytes
$(document).ready(function()
{
$(".upload_file").find(".upload_button").click(send_file);
$(".upload_file").find(".upload_file_form").find("input[type='file']").click(enable_upload);
});
function send_file()
{
if ($(this).attr("enabled") != "true") return;
// Prevent double-triple clicks with multiple upload.
$(this).attr("enabled", "false");
var form = $(this).parent().find(".upload_file_form").get(0);
var formData = new FormData(form);
var file = $(form).find("input[type='file']").get(0).files[0];
// Not sure about this
// Prevent attack with HUGE files, that will smash server memory
// TODO: Restrict file types (Ex. MIME-image, pdf, doc)
if (file.size > SIZE_RESTRICT)
{
alert("File is too big.");
return;
}
formData.append("proof_type", $(this).attr("upload-type"));
var xhr = new XMLHttpRequest();
var that = this;
// TODO: Define another events like error, abort
xhr.upload.onprogress = function(e) {
// TODO: Progressbar as e.loaded / e.total
if (e.lengthComputable)
console.log((e.loaded / e.total) * 100);
else
console.log("Cant count length");
};
xhr.onload = function(e){
// TODO: Show success confirmation to user.
if (this.response == "Success")
{
// pass
alert(this.response);
}
else if (this.response == "Error")
{
// pass
alert(this.response);
}
else
{
// pass
}
};
xhr.open('POST', '/upload_proof');
xhr.send(formData);
}
function enable_upload()
{
$(this).parent().parent().find(".upload_button").attr("enabled", "true");
}
Actually another simple example could be founded in docs
If the set of images is small and fixed, the best option is to use the choice attribute in the field that defines the image within your model.
The image field could be the path to the image file on the file system.
class UserProfile(models.Model):
GOOD = 'Good.jpg'
UGLY = 'Ugly.jpg'
BAD = 'Bad.jpg'
AVATAR_CHOICES = (
(GOOD, 'Good'),
(UGLY, 'Ugly'),
(BAD, 'Bad'),
)
avatar_img = models.CharField(max_length=255,
choices=AVATAR_CHOICES,
default=GOOD)
Another option is to use FilePathField as your model field
FilePathField(path="/path/to/avatar_images", match="*.jpg", recursive=False)
Another way is to fill the form field dynamically when the form is instantiated.
Please see this SO QA for more on that.
However, as Django docs say
But if you find yourself hacking choices to be dynamic, you’re
probably better off using a proper database table with a ForeignKey
To specify Radiobuttons to be used for the form field, please refer to the official docs on how to set the proper widget.

Categories

Resources