I'm trying in Django to render from html to pdf a monthly report that takes data from a database by month.
I need to send the selected month on the html page to the class that creates the Pdf. How can I do that?
My view class :
class view_pdf_monthly_report(View):
def get(self, request, *args, **kwargs):
push = {'month':month}
pdf = render_to_pdf('home/pdf_monthly_inquiries_report.html', push)
return HttpResponse(pdf, content_type='application/pdf')
My html: how can I send the month from here?
<div class="text-center">
<a class="btn btn-info" href="{% url 'view_pdf_monthly_report'%}" target="_blank">View PDF</a>
</div>
Thanks !
first create a simple form which will send month data to your view
<div class="text-center">
<form action="{% url 'view_pdf_monthly_report'%}" method="get">
<input type="hidden" value="{{month}}" name="month">
<button class="btn btn-info" type="sumbit">View PDF</button>
</form>
</div>
and then inside your views
class view_pdf_monthly_report(View):
def get(self, request, *args, **kwargs):
month = request.GET.get('month')
push = {'month':month}
pdf = render_to_pdf('home/pdf_monthly_inquiries_report.html', push)
return HttpResponse(pdf, content_type='application/pdf')
Related
I created the form and added it to view, how I must add it to html form?
index.html
<form action="." method="post">
{{ form.as_p }}
{% csrf_token %}
<p><input type="submit" value="Add comment"></p>
</form>
<h1 style="margin:0 57%">Reviews</h1>
<input type="hidden" name="parent" id="contactparent" value="">
<div class="dfv" style="display:flex; padding: 5%; justify-content: space-around; flex-wrap: wrap;align-items:center; box-shadow:4px 4px 16px gold;width: 80%;margin:8% 18% 0">
<div class="form-group editContent">
<label for="contactcomment" class="editContent" placeholder=" Message" >
Your reviews *
</label>
views.py
class AddReview(View):
"""Отзывы"""
def post(self, request,pk):
form = ReviewForm(request.POST,)
if form.is_valid():
form = form.save(commit=False)
#form.Dish = Dish
form.save()
review = Reviews.objects.all()
return render(request,'index.html',{'Reviews':review})
forms.py
class ReviewForm(ModelForm):
class Meta:
model = Reviews
fields = ('name', 'email', 'text')
urls.py
path("review/<int:pk>/", AddReview.as_view(), name='add_review'),
Request not found. Request URL: http://127.0.0.1:8000/%7Burl%20'add_review'%20dish.id%7D
enter code here
enter code here
Answer to the original question as to how to add the form to your HTML is to put the form into the context that is sent to the template:
{'form': form, 'Dish': dish, 'Snack': snack, 'Desserts': desserts, 'Lastcourses': lastcourses, 'Reviews': reviews}
Now for the rest. Here's what I had before you made all the changes to your code. The problem, I think is you're mixing function based views with class based views together in the same view. Second, you are handling either get or post when you need to handle both in the same view.
class DishView(View):
form_class = ReviewForm
template_name = 'index.html'
def get(self, request, *args, **kwargs):
form = self.form_class()
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
form = form.save(commit=False)
form.name = request.name
form.text = request.text
form.save()
return redirect(self.path)
return render(request, self.template_name, {'form': form})
I also think you have an error in your form tag. If you want the form to be submitted back to the same view, then you don't use ".". You can leave the action out:
<form method="post">
<!-- OR -->
<form action="" method="post">
I have a form that's just a date field and submit button
Forms.py
from django import forms
from datetime import date
class DateInput(forms.DateInput):
input_type = 'date'
class HomeForm(forms.Form):
EnterDate = forms.DateField(widget=DateInput, initial=date.today())
Because of a user request, I just want to send the data to the url like this
home/2021-07-01
so I tried to do this for my html form, just stick the form.EnterDate.value in the form Action part, but it only works on the 2nd try.
<form method="POST" class="form-inline my-2 my-lg-0" action="{% url 'mint-post' form.EnterDate.value %}">
{% csrf_token %}
<label for="{{form.EnterDate.id_for_label}}">Enter Date</label>
{{form.EnterDate}}
<button class="btn btn-primary my-2 my-sm-0" type="submit">Submit Date</button>
#Inital loading the form
def mintHome(request):
form = HomeForm()
context = {
'form': form }
return render(request, 'mintyHome.html', context)
#after Post
def mintHomePost(request, pk):
if request.method =='POST':
form = HomeForm(request.POST)
if form.is_valid():
datePost = form.cleaned_data['EnterDate']
stringDate = datePost.strftime("%Y%m%d")
context = {
'form': form }
return render(request, 'mintyHome.html', context)
I made an example here:
https://alisayt.pythonanywhere.com/minty/home
It sends the form.EnterDate.value only in the 2nd submit, but not the first one.
Do you want the POST request to be sent to a URL based on the current date? Or to a URL based on the user input?
The template code {% url 'mint-post' form.EnterDate.value %} is only executed once on the server when you request the page, not when you change the date input and submit the POST request.
If you would like the action URL to change with the user input, this has to happen on the client side, i. e. using JavaScript.
im following a tuto on how ajax work on Django, its my first time with ajax and im facing a little problem ,the data insertion is working but the success ajax dont redirect corectly, and thank you for the help
this the code
views.py :
class exo(View):
def get(self, request):
form = ExerciseForm()
tasks = task.objects.all()
context = {
'form': form,
'tasks': tasks
}
return render(request, 'coach/test.html',
context=context)
def post(self, request):
form = ExerciseForm()
if request.method == 'POST':
form = ExerciseForm(request.POST)
print(form)
if form.is_valid():
print('adding task', form)
new_exrercise = form.save()
return JsonResponse({'task': model_to_dict(new_exrercise)}, status=200 )
else:
print('not adding task')
return redirect('exo')
ajax function :
$(document).ready(function(){
$("#addExercise").click(function() {
var serializedData = $("#TaskForm").serialize();
$.ajax({
url: $("TaskForm").data('url'),
data : serializedData,
type: 'post',
success: function(response) {
$("#taskList").append('<div
class="card"><div class="card-body">'+ response.task.name
+'<button type="button" class="close float-right"> <span
aria-hidden="true">×</span></button></div></div>');
}
})
});
});
html content :
<form class="submit-form" method="post" id="TaskForm"
data-url="{% url 'session' %}">
{% csrf_token %}
<div class="form-group">
{% for field in form %}
<div style="margin-bottom: 2rem;"></div>
{{field}}
{% endfor %}
<div style="margin-bottom: 2rem;"></div>
<button type="submit" class="btn btn-success dropdown-toggle " id="addExercise">Confirm</button>
</div>
</form>
this is what i get (i get an object and nothing else )
output image
when i comeback to the page exo the insertion is done
and the console show me that the post is sending well :
[21/Dec/2020 22:25:38] "POST /coach/exo/ HTTP/1.1" 200 43
The problem is that your button:
<button type="submit" class="btn btn-success dropdown-toggle " id="addExercise">Confirm</button>
will submit the form, and not (only) by the AJAX call, but simply by the fact that you made it a submit button. This thus means that the browser will encode the form and make a POST request with that form, and then the browser will render the response.
You thus should remove the type="submit" part from the button:
<button class="btn btn-success dropdown-toggle " id="addExercise">Confirm</button>
I remove the submit type and nothing was working , the button wasnt posting anything to ajax then i switch my view class into a function and it work i really dont know why there is the view
def addsession(request):
template = loader.get_template('coach/addexercise.html')
exercises = exercise.objects.all()
# context = {'exercises': exercises}
UpperBody = exercise.objects.filter(category__name="Upper Body")
LowerBody = exercise.objects.filter(category__name="Lower Body")
FIIT = exercise.objects.filter(category__name="FIIT")
LIIT = exercise.objects.filter(category__name="LIIT")
form = ExerciseForm()
tasks = task.objects.all()
context = {'exercises': exercises,
'UpperBody': UpperBody,
'LowerBody': LowerBody,
'FIIT': FIIT,
'LIIT': LIIT,
'form': form,
'tasks': tasks
}
form = ExerciseForm()
if request.method == 'POST':
form = ExerciseForm(request.POST)
print(form)
if form.is_valid():
print('adding task', form)
new_exrercise = form.save()
return JsonResponse({'task': model_to_dict(new_exrercise)}, status=200 )
else:
print('not adding task')
return redirect('session')
return render(request, 'coach/addexercise.html', context=context)
and thank u guys for your answers i really didnt give attention to the input type of button
I am only trying to test the default user profile update through UserChangeForm. Just the email field. So below are the code snippet.
views.py
#login_required(login_url="/login/")
def editUserProfile(request):
if request.method == "POST":
form = UserProfileUpdateForm(request.POST, instance=request.user)
if form.is_valid():
form = UserProfileUpdateForm(request.POST)
form.save()
return redirect('thank_you')
else:
messages.error(request, f'Please correct the error below.')
else:
form = UserProfileUpdateForm(instance=request.user)
return render(request, "authenticate\\editProfilePage.html", {'form': form})
forms.py
class UserProfileUpdateForm(UserChangeForm):
email = forms.EmailField()
class Meta:
model = User
fields = ('email', )
HTML
<div class="container h-100">
<div class="d-flex justify-content-center h-100">
<div class="user_card">
<div class="d-flex justify-content-center">
<h3 id="form-title">Update Profile</h3>
</div>
<div class="d-flex justify-content-center form_container">
<form method="POST" action="{% url 'editUserProfile' %}">
{% csrf_token %}
<div class="input-group mb-2">
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-envelope-square"></i></span>
</div>
{{form.email}}
</div>
<div class="d-flex justify-content-center mt-3 login_container">
<input class="btn login_btn" type="update" value="update">
</div>
</form>
</div>
{{form.errors}}
<script>
/* Because i didnt set placeholder values in forms.py they will be set here using vanilla Javascript
//We start indexing at one because CSRF_token is considered and input field
*/
//Query All input fields
var form_fields = document.getElementsByTagName('input')
form_fields[4].placeholder='email';
for (var field in form_fields){
form_fields[field].className += ' form-control'
}
</script>
</body>
In the user profile page, I could see the update button, and when I click on it I am redirected to the edit profile page, and I am also able to see the old email address mentioed in the email field. So far so good.
However, when I replace the old email with new one and click on the "update" button nothing happens. No error, no redirection. Nothing. The page remains there.
There were sytax errors in my HTML code, so I re-wrote the entire HTML again. That resolved the issue. Thank you
I'm making an app to save mileage of a truck per state. I've already passed required data to my view, and then I thought to change my urls to more logical. And after that I faced a problem.
I don't know what should be instead of "unit.unit_number", and it is required, in my html file for it to work correctly. I didn't find anything that could explain how to deal with it.
If I try to access mywebsite.com/core/units/1/locations/add/ I get next error message:
"NoReverseMatch at /core/units/1/locations/add/"
But if I put just a number (1 for example) instead of "unit.unit_number" it loads the page normally, but I get an error after trying to post the data:
"TypeError at /core/units/1/locations/add/
_reverse_with_prefix() argument after * must be an iterable, not int"
<form action="{% url 'Core:unit_add_location' unit.unit_number %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="container">
<div class="inner-container border-full">
<button type="button" class="button button-normal" onclick="AddRow()">Add</button>
<input type="submit" class="button button-submit" name="count-ifta" value="Save">
<div class="inner-container border-top-bottom">
<table id="myTable" name="state-miles-data">
<thead>
<th class="text-blue">State</th>
<th class="text-blue">Miles</th>
</thead>
</table>
<br>
</div>
</form>
<button type="button" class="button button-normal" onclick="AddRow()">Add</button>
</div>
</div>
def unit_data(request, unit_number):
return HttpResponse(unit_number)
def unit_add_location(request, unit_number):
if "GET" == request.method:
return render(request, 'Core/add_location.html')
elif "POST" == request.method:
states_request = request.POST.getlist('states')
miles_request = request.POST.getlist('miles')
return HttpResponseRedirect(reverse('Core:unit_data', args=(unit_number)))
urlpatterns = [
path('units/', views.units_all, name = 'units_all'),
path('units/<int:unit_number>/', views.unit_data, name = 'unit'),
path('units/<int:unit_number>/locations/', views.unit_locations, name = 'unit_locations'),
path('units/<int:unit_number>/locations/add/', views.unit_add_location, name = 'unit_add_location'),
path('units/<int:unit_number>/locations/<int:report_id>', views.unit_location, name = 'unit_location'),
]
So the thing I want to make is post the data and redirect to url "mywebsite.com/units/1/locations/" that is processed by the view "unit_locations"
To the second part about the iterable: (reverse('Core:unit_data', args=(unit_number))) <<< you want (unit_number,) which is a tuple not an int. Spot the , it is important.