so i have this two views, one used to display information and one that returns a file responde. I am trying to download a pdf file using the information on the first view:
#login_required()
def detail(request, location_name):
if request.method == "POST":
return search_in_employees(request)
current = CurrentInfo()
pdf_data = current.detail_employees_by_location(location_name) # this gives me the list of people
context = {
'present': current.detail_employees_by_location(location_name),
'location': location_name,
}
print('Data: -------------->', pdf_data)
return render(request, 'user_area/detail.html', context)
and my second view just formats it as a pdf:
#login_required()
def download_pdf(request):
buf = io.BytesIO()
canv = canvas.Canvas(buf, pagesize=letter, bottomup=0)
textob = canv.beginText()
textob.setTextOrigin(inch, inch)
textob.setFont("Helvetica", 14)
lines = [
"Line 1 ",
"Line 2 ",
"Line 3 ",
"Line 4 ",
]
for line in lines:
textob.textLine(line)
canv.drawText(textob)
canv.showPage()
canv.save()
buf.seek(0)
return FileResponse(buf, as_attachment=True, filename='employees.pdf')
Right now the PDF file only contains dummy data, but how can i pass pdf_data from the first view to the second?
I would suggest creating a function either inside your views.py or inside a helpers.py file in your module:
def get_pdf_data(location_name):
current = CurrentInfo()
pdf_data = current.detail_employees_by_location(location_name)
return pdf_data
Then your first view would look like:
#login_required()
def detail(request, location_name):
if request.method == "POST":
return search_in_employees(request)
pdf_data = get_pdf_data(location_name)
context = {
'present': pdf_data,
'location': location_name,
}
print('Data: -------------->', pdf_data)
return render(request, 'user_area/detail.html', context)
And your second view can use this new function but only if you send the location_name to the view same as the first view
#login_required()
def download_pdf(request, location_name):
pdf_data = get_pdf_data(location_name)
buf = io.BytesIO()
canv = canvas.Canvas(buf, pagesize=letter, bottomup=0)
textob = canv.beginText()
textob.setTextOrigin(inch, inch)
textob.setFont("Helvetica", 14)
for line in pdf_data:
textob.textLine(line)
canv.drawText(textob)
canv.showPage()
canv.save()
buf.seek(0)
return FileResponse(buf, as_attachment=True, filename='employees.pdf')
Related
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.
I'm just learning python and django.
I am writing a thing that reads the values in the xlsx file, and if the values are similar to those in the database, then the value in the adjacent column in the xlsx file changes to the one I specify
models.py
class imgUpload(models.Model):
title = models.CharField(max_length=100)
img = models.ImageField(upload_to='img')
def __str__(self):
return self.title
views.py
def upload_xlsx(request):
if request.method == 'POST':
form = xlsxForm(request.POST, request.FILES)
if form.is_valid():
form.save()
fileName = xlsxUpload.objects.last()
fileNameStr = str(fileName.file)
book = load_workbook(fileNameStr)
sheet: worksheet = book.worksheets[0]
for row in range(2, sheet.max_row + 1):
a = sheet[row][0].value
fileNameImg = imgUpload.objects.all()
fileNameImgStr = fileNameImg.filter(title=a)
if a == fileNameImgStr:
sheet[row][1].value = str(fileNameImgStr)
book.save(fileNameStr)
book.close()
return redirect('xlsx_list')
else:
form = xlsxForm()
return render(request, 'img/upload_xlsx.html', {
'form': form
})
I have achieved that it takes all the values, but does not compare them
I am receiving the following error when submitting a form.
ValueError at /edit_entry/hi/
The view encyclopedia.views.edit_entry didn't return an HttpResponse object. It returned None instead.
Here is the views.py that is triggering the error.
def edit_entry(request, title):
if request.method == "POST":
form = NewEditEntryForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
util.save_entry(title, content)
return HttpResponseRedirect("/wiki/" + title)
else:
form = NewEditEntryForm()
return render(request, "encyclopedia/edit_entry.html",{
"form": NewEditEntryForm(),
"title": title,
"content": util.get_entry(title)
})
What is the issue and how can I fix it?
(I also need help prepopulating the form with already existing data. I have tried using initial, but that has not worked. What is the best way to prepopulate the form with existing data?)
util.save_entry
def save_entry(title, content):
"""
Saves an encyclopedia entry, given its title and Markdown
content. If an existing entry with the same title already exists,
it is replaced.
"""
filename = f"entries/{title}.md"
if default_storage.exists(filename):
default_storage.delete(filename)
default_storage.save(filename, ContentFile(content))
sorry, I thought that you have a model.
# on util.py
def get_entry_content(title):
filename = f"entries/{title}.md"
return default_storage.open(filename).read()
# on views.py
def edit_entry(request, title):
if request.method == "POST":
form = NewEditEntryForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
util.save_entry(title, content)
return HttpResponseRedirect("/wiki/" + instance.title)
else:
content = util.get_entry_content(title)
initial_dict = {
"title" : title,
"content" : content,
}
form = NewEditEntryForm(initial=initial_dict)
return render(request, "encyclopedia/edit_entry.html", {
"form": form,
})
All right, I think if this is not doing what you want, i would test the save_entry function in the console, creating and updating to see if it works or not.
I am submitting csv file from form using POST method and want to save its content into model
forms.py
class SaveCsvForm(forms.Form):
upload_file = forms.FileField(label="Uplaod CSV File", help_text="Uploa file in CSV format")
Views.py
def save_csv(request):
if request.method == 'POST':
form = SaveCsvForm(request.POST, request.FILES)
if form.is_valid():
print("All ok I am check One")
# instance = CsvStorage(file_field=request.FILES['file'])
file = request.FILES['upload_file'].read()
print(file)
csv_to_db(file)
ack = {
'status': 'Success',
'message': 'Data is successfuly submited into database'
}
return JsonResponse(ack)
else:
ack = {
'status': 'Error',
'message': 'Server Returned '+form.errors.as_json(),
}
return JsonResponse(ack)
else:
form = SaveCsvForm()
return render(request, 'upload_csv.html', {'form': form})
file handler method for storing data in Model
def csv_to_db(filename):
with open(filename, 'r') as file:
''' reading csv file in dictionary format '''
reader = csv.DictReader(file)
for row in reader:
instance = CsvStorage(username=row['username'],
first_name=row['user'],
city=row['city'],
mobile=row['mobile']
)
instance.save()
if instance:
return({'status': 'successfuly'})
else:
return({'status': 'error'})
Note:
1.The main problem is while reading the file
2.I don't want to store file in models fileField
I ended up using FileSystemStorage class in Django as described in docs.
Here's my code
#login_required
def upload(request):
form_type = ''
transcript = Transcript()
transcript.file_path = ''
if request.method == 'POST':
if 'file_form' in request.POST:
file_form = FileForm(request.POST, request.FILES)
if file_form.is_valid():
path = handle_uploaded_file(request.FILES['file'], request.user)
transcript.file_path = path
transcript.user = request.user
export_form = InfoForm()
form_type = 'info_form'
elif 'info_form' in request.POST:
if transcript.file_path:
info_form = InfoForm(request.POST)
if info_form.is_valid():
transcript.user = request.user
transcript.title = info_form.cleaned_data.get('title')
transcript.instructions = info_form.cleaned_data.get('instructions')
transcript.save()
return HttpResponseRedirect('thanks')
else:
raise ValueError('Transcript object has no file path attribute')
else:
export_form = FileForm()
form_type = 'file_form'
return render(request, 'transcription/upload.html', {'form': export_form, 'form_type': form_type})
always, the file-form is called before the info-form, so the code in the if statement
if transcript.file_path:
#...
should always execute. But the ValueError always gets raised, meaning transcript.file_path is reset. How does this happen, and how can it be fixed?
file_form and info_form in POST are names of the different submit buttons, so I know which form I am dealing with.
def handle_uploaded_file(file, user):
id = randint(0, 10000)
user_dir = settings.MEDIA_ROOT + '/' + str(user.id).replace(".", "") + '/'
path = user_dir + file.name.replace(".mp3", str(id) + ".mp3")
if not os.path.exists(user_dir):
os.makedirs(user_dir)
with open(path, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
file = File(destination)
info = {'path': path, 'file': file}
return path
So it was a rookie mistake.
I didn't know that during each post request the whole view gets called again.
So I just initialized my variables
form_type = ''
transcript = Transcript()
transcript.file_path = ''
outside the view and voila!