Display PDF in django - python

I need to display a pdf file in a browser, but I cannot find the solution to take the PDF for the folder media, the PDF file was save in my database, but I cannot show.
my urls.py:
urlpatterns = [
path('uploadfile/', views.uploadFile, name="uploadFile"),
path('verPDF/<idtermsCondition>', views.verPDF, name='verPDF'),
]
my models.py:
class termsCondition(models.Model):
title = models.CharField(max_length=20, verbose_name="title")
uploadPDF = models.FileField(
upload_to="PDF/", null=True, blank=True)
dateTimeUploaded = models.DateTimeField(auto_now_add=True)
deleted_at = models.DateTimeField(
auto_now=False, verbose_name="Fecha eliminacion", blank=True, null=True)
class Meta:
verbose_name = "termsCondition"
verbose_name_plural = "termsConditions"
my views.py:
def uploadFile(request):
user = request.user
if user.is_authenticated:
if user.is_admin:
if request.method == "POST":
# Fetching the form data
fileTitle = request.POST["fileTitle"]
loadPDF = request.FILES["uploadPDF"]
# Saving the information in the database
termscondition = termsCondition.objects.create(
title=fileTitle,
uploadPDF=loadPDF
)
termscondition.save()
else:
listfiles = termsCondition.objects.all()[:1].get()
return render(request, 'subirTerminos.html', context={
"files": listfiles
})
else:
messages.add_message(request=request, level=messages.SUCCESS,
message="No tiene suficientes permisos para ingresar a esta página")
return redirect('customer')
else:
return redirect('login2')
def verPDF(request, idtermsCondition):
user = request.user
if user.is_authenticated():
if user.is_admin:
getPDF = termsCondition.objects.get(pk=idtermsCondition)
seePDF = {'PDF': getPDF.uploadPDF}
print(seePDF)
return render(request, 'subirTerminos.html', {'termsCondition': getPDF, 'uploadPDF': getPDF.uploadPDF})
else:
messages.error(request, 'Do not have permission')
else:
return redirect('login2')
my html:
<div>
<iframe id="verPDF" src="media/PDF/{{ uploadPDF.url }}"
style="width:800px; height:800px;"></iframe>
</div>
I want to see my pdf and I cannot do, I want to know how to do, I tried many solutions, I accept js, embed iframe whatever to can solve.

It should be user.is_authenticated not user.is_authenticated() in verPDF view and also I'd recommend you to change <idtermsCondition> to <int:idtermsCondition> as by default (if nothing is given) it is considered as string.
urls.py
urlpatterns = [
path('uploadfile/', views.uploadFile, name="uploadFile"),
path('verPDF/<int:idtermsCondition>/', views.verPDF, name='verPDF'),
]
And the {{uploadPDF.url}} already has the url (full path to the media directory) and try to use <embed> tag so:
<div>
<embed id="verPDF" src="{{uploadPDF.url}}" width="500" height="375" type="application/pdf">
</div>
Note: Always add / at the end of every route

Finally I can solve it, I had problems in my views.py and in the html, when I called uploadPDF my views called another name which was loadpdf and when I rendered it it was another name.
now, views.py:
``def uploadFile(request):
user = request.user
if user.is_authenticated:
if user.is_admin:
if request.method == "POST":
# Fetching the form data
fileTitle = request.POST["fileTitle"]
loadPDF = request.FILES["uploadPDF"]
if termsCondition.objects.all().exists():
listfiles = termsCondition.objects.all()[:1].get()
listfiles.uploadPDF = loadPDF
listfiles.save()
else:
# Saving the information in the database
termscondition = termsCondition.objects.create(
title=fileTitle,
uploadPDF=loadPDF
)
return redirect('uploadFile')
else:
if termsCondition.objects.all().exists():
listfiles = termsCondition.objects.all()[:1].get()
return render(request, 'subirTerminos.html', context={
"files": listfiles.uploadPDF
})
else:
listfiles = {}
return render(request, 'subirTerminos.html', context={"files": listfiles})
else:
messages.add_message(request=request, level=messages.SUCCESS,
message="No tiene suficientes permisos para ingresar a esta página")
return redirect('customer')
else:
return redirect('login2') ``
and html:
<h1 class="title">Visualizador de PDF</h1>
<embed id="verPDF" src="{{files.url}}" width="500" height="375" type="application/pdf">

Related

Python, Django, HTMX, is it possible to save data, when a user clicks <button>

When a user click <button> on index page, can save data immediately?
views.py
def index(request):
...
...
context = { ... }
response = render(request, 'docu/index.html', context)
### Save visitors' IP and Keywords to KeyLOG table ###
ip = request.META.get('REMOTE_ADDR')
keywords = request.META.get('HTTP_REFERER', '')
keylog = KeylogForm(request.GET)
keylog = keylog.save(commit=False)
keylog.ipaddr = ip
keylog.keyquery = keywords
keylog.svae()
return response
def keylog(request):
if request.method == "GET":
keylog_list = list(Keylog.objects.all().order_by()\
.values('idpaddr', 'keywords', 'tel_log', 'regtime'))
return JsonResponse(keylog_list, safe=False)
return JsonResponse({'message':'error'})
forms.py
class KeylogForm(forms.ModelForm):
class Meta:
model = Keylog
fields = ['ipaddr','keyquery','tel_log']
models.py
class Keylog(models.Model):
ipaddr = models.CharField(max_length=32,null=True, blank=True) #save IP addr
keyquery = models.CharField(max_length=128,null=True, blank=True) #save keywords
tel_log = models.CharField(max_length=256,null=True, blank=True) #save tel_log
regtime = models.DateTimeField(auto_now_add=True) #created time
Currently, it makes table as below;
Ipaddr
keyquery
tel_log
regtime
192.168.x.yy
?query=apple
2023.01.01.12.24.56
192.168.a.bb
?query=banana
2023.01.01.11.22.33
I hope to save Tel_log data in the above table, when a user clicks <butto>...</button>.
So I made an index.html as below;
index.html
<div id="tel_log">
<button class="btn btn-danger">
hx-get="keylog/"
hx-vals="[tel_log='CALL']"
hx-trigger="click">
Phone NUMBER
</button>
</div>
My expectation is that when I clicked [Phone NUMBER] on the index page, "CALL" is appeared on the "tel_log" column of the above table, but it didn't work, just shows {message:error}
I'm a newbie on programming, so my approach for my needs may be wrong, but I'm really eager to make a web site for now, especially on this question. I also did try to use Ajax, but I didn't get any response also.
Thank you for all.
Click [button], save data in real time on the column of the table.

Django ValueError (The view views.save_flow_data didn't return an HttpResponse object. It returned None instead.)

When I try to submit my form I get this message:
The view views.save_flow_data didn't return an HttpResponse object. It returned None instead.
Views.py
def save_flow_data(request):
if request.method == 'POST':
if request.POST.get('upload_flow') \
and request.POST.get('water_flow_rate')\
and request.POST.get('water_flow_rate_unit')\
data=CalcData()
data.water_flow_rate = request.POST.get('water_flow_rate')
data.water_flow_rate_unit = request.POST.get('water_flow_rate_unit')
data.save()
return render(request, 'io/flow.html')
else:
return render(request,'io/flow.html')
models.py
class CalcData(models.Model):
upload_flow = models.BooleanField(default=False)
water_flow_rate = models.DecimalField(max_digits=100, decimal_places=5)
water_flow_rate_unit = models.TextChoices('wfr_unit', 'm3/day m3/month')
datetime = models.DateTimeField(default=timezone.now)
submit button in form
<div>
<button action="{% url 'MyProject:save_flow_data' %}" type="submit" class="btn btn-light" style="width: 517.5px;" >Calculate</button>
</div>
urls.py
urlpatterns = [
path('', views.home, name='MyProject-home'),
path('io/flow/', views.io_flow, name='MyProject-io-flow'),
path('io/flow/save_flow_data', views.save_flow_data, name='save_flow_data')
]
I'm really not sure where to go from here. I had a perfectly working form but as soon as I scaled it up it flopped.
The case
if request.POST.get('upload_flow') \
and request.POST.get('water_flow_rate')\
and request.POST.get('water_flow_rate_unit')\
is False is not covered.
You need to either remove the last else :
def save_flow_data(request):
if request.method == 'POST':
if request.POST.get('upload_flow') \
and request.POST.get('water_flow_rate')\
and request.POST.get('water_flow_rate_unit')\
data=CalcData()
data.water_flow_rate = request.POST.get('water_flow_rate')
data.water_flow_rate_unit = request.POST.get('water_flow_rate_unit')
data.save()
return render(request, 'io/flow.html')
return render(request,'io/flow.html')
Or add a return to the uncovered path:
def save_flow_data(request):
if request.method == 'POST':
if request.POST.get('upload_flow') \
and request.POST.get('water_flow_rate')\
and request.POST.get('water_flow_rate_unit')\
data=CalcData()
data.water_flow_rate = request.POST.get('water_flow_rate')
data.water_flow_rate_unit = request.POST.get('water_flow_rate_unit')
data.save()
return render(request, 'io/flow.html')
return render(request, 'io/flow.html') # Or return something else
else:
return render(request,'io/flow.html')
Remove else statement and keep indentation of:
return render(request,'io/flow.html')
At function level.

Is there an effcient way to perform search query in django?

I'm creating a blog in which i want to perform a search query based on ones rating (1-5). Here my search would be like query:"smart phone tech updates", rating:"3". Result should be list of post that contains query word(at least one word) which has rating 3, in a sorted way on val(for each query word, if found in title val+=1 if found in content val+=0.4).
My models.py file has the following :
class Post(models.Model):
title = models.CharField(max_length=50)
content = models.CharField(max_length=500)
rating = models.IntegerField(default=1)
enter code here
date = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
My view.py file has the following:
def search(request):
contents = Post.objects.all()
if request.method == 'GET':
query = request.GET['query']
rating = request.GET['rating']
# search function
# contents = InSearch.search_fun(contents,query,rating)
vector = SearchVector('title', weight='A') + SearchVector('content', weight='B')
qry = SearchQuery(str(query))
contents = Post.objects.annotate(rank=SearchRank(vector, qry)).order_by('-rank')
#print("---->\n\t"+query+ str(contents))
context = {
'contents': contents
}
else:
context = {
'contents': Post.objects.all()
}
return render(request, 'feed/home.html', context)
My urls.py is:
urlpatterns = [
#...
path('feed/search-result/', views.search, name='feed_search'),
]
I'm getting this error
django.db.utils.OperationalError: no such function: plainto_tsquery
You can try like this in your views for searching.
from django.db.models import Q
def search(request):
q = request.GET.get('q')
if q:
search_results = Post.objects.filter(Q(title__icontains=q)|Q(rating=q))
# if you want the exact then do Post.objects.filter(Q(title__iexact=q) & Q(rating=q))
return render(request, 'feed/home.html','search_results':search_results)
else:
messages.info(request,'no results found for {}',format(q))
If you want to sort search query result by number of matches then you can try like this:
search_results = Post.objects.filter(Q(title__icontains=q)|Q(rating=q)).annotate(title_counts=Count('title')).order_by('-title_counts')
And in your template give name='q' in the search form.
<form action="{% url 'your search action' %}">
<input type="text" name="q">
<input type='submit' value='Search'>
</form>

'str' does not support the buffer interface while uploading and submitting csv file in Django

I want to upload a csv file and store it in a database. My Django version is 1.9 and Python3.4. Below is the code. My app name is 'pft'
pft/utils.py
from .models import Account
import csv
def handle_uploaded_file(file, valid_fields_method, record_creation_function):
file.seek(0)
# !importtant
# csv file must be encoded in UTF-8
sniffdialect = csv.Sniffer().sniff(file.read(10000), delimiters='\t,;')
file.seek(0)
#print sniffdialect.fieldnames
data = csv.DictReader(file, dialect=sniffdialect)
if not valid_fields_method(data.fieldnames):
return False, -1
result, rows_error = record_creation_function(data)
return result, rows_error
def account_valid_fields(field_names):
required_fields = ('species', 'x', 'y')
for field in required_fields:
if field not in field_names:
return False
return False
def create_account_in_db(dict_data):
list_data = []
result = False
rows_error = 0
for record in dict_data:
species = record['species']
x = record['x']
y = record['y']
account = models.Account(species=species,\
x=x,\
y=y)
list_data.append(account)
if list_data:
# bulk_create will create multiple object in a single query
created_accounts = models.Account.objects.bulk_create(list_data)
if len(list_data) == len(created_accounts):
result=True
else:
rows_error = len(list_data) - len(created_accounts)
return result, rows_error
models.py
class Account(models.Model):
species=models.CharField(max_length=255)
x=models.IntegerField()
y=models.IntegerField()
last_modified = models.DateTimeField(auto_now = True)
first_created = models.DateTimeField(auto_now_add = True)
def __str__(self):
return "%s %s %s" % (self.species, self.x,self.y)
views.py
def add_multiple_accounts(request):
if request.method == 'POST':
csv_upload_form = UploadFileForm(request.POST, request.FILES)
if csv_upload_form.is_valid():
file = csv_upload_form.cleaned_data['file']
csv_result, rows_error = utils.handle_uploaded_file(file, utils.account_valid_fields, utils.create_account_in_db)
if csv_result:
message = 'Successfully imported accounts from the csv file to the database.\n'
message += 'The system is creating Active Directory Accounts using those information in the background.\n'
message += 'Please wait...'
messages.add_message(request, messages.INFO, message)
else:
message = 'There are some errors occured. Please try again.'
messages.add_message(request, messages.INFO, message)
else:
csv_upload_form = UploadFileForm()
return render_to_response('add_multiple.html', locals(), context_instance=RequestContext(request))
urls.py
url(r'^csv',add_multiple_accounts),
add.mutilple.html
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ csv_upload_form.as_p }}
<button type="submit" class="action green btn-center" name="action" value="add_csv"><span class="label">Upload</span></button>
<input type="submit" />
</form>
When I click the submit button I get the above error. How can I solve this?
try:
file_content = bytes(file.read(10000), 'UTF-8')
sniffdialect = csv.Sniffer().sniff(file_content, delimiters='\t,;')
it is because string in Python3.x is not the same as in python2.x, you need to cast it with bytes and encode as utf-8

The submitted data was not a file. Check the encoding type on the form in DRF 3

OutputError
{
"item_image": [
"The submitted data was not a file. Check the encoding type on the form."
],
"item_thumb": [
"The submitted data was not a file. Check the encoding type on the form."
]
}
Data which I'm posting is
input
{
"item_name": "Lural",
"item_image": "/home/prashant/Desktop/suede.png",
"item_thumb": "/home/prashant/Desktop/suede.png",
"item_description": "sd",
"item_mass": 1,
"item_category": "Make Up",
"item_sub_category": "Sub-Feminine",
"item_est_price": "123.12",
"item_wst_price": "120.34"
}
for media type application/json
views.py
#api_view(['GET', 'POST'])
def product_list(request):
if request.method == 'POST':
serializer = ProductSerializer( data=request.data)
# data.encode("base64")
if serializer.is_valid():
serializer.save()
res_msg = {'Success_Message' : 'Created','Success_Code' : 201}
return Response(res_msg)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
models.py
class Product(models.Model):
item_category_choices = (
('Make Up','Make Up'),
('Skin Care','Skin Care'),
('Fragrance','Fragrance'),
('Personal Care','Personal Care'),
('Hair Care','Hair Care'),
)
item_name = models.CharField(max_length=50)
item_image = models.ImageField()
item_thumb = models.ImageField()
item_description = models.TextField(max_length=200)
item_mass = models.IntegerField()
item_category = models.CharField(max_length=20,choices = item_category_choices)
item_sub_category = models.CharField(max_length=20)
item_est_price = models.DecimalField(max_digits=15,decimal_places=2)
item_wst_price = models.DecimalField(max_digits=15,decimal_places=2)
def __unicode__(self):
return self.item_name or _('Sprint ending %s')% self.item_avg_price
serializers.py
class ProductSerializer(ModelSerializer):
class Meta:
model = Product
fields = ('id','item_name' ,'item_image','item_thumb','item_description','item_mass','item_category',
'item_sub_category','item_est_price','item_wst_price',)
tried many forums & third party packages too but their isn't any way out from this problem.
Also GET is working totally fine.
Thanks for your time
From Django Docs -
If you intend to allow users to upload files, you must ensure that the
environment used to run Django is configured to work with non-ASCII
file names. If your environment isn’t configured correctly, you’ll
encounter UnicodeEncodeError exceptions when saving files with file
names that contain non-ASCII characters.
Thus adding this method to the model solved my problem :
class Product(models.Model):
item_category_choices = (
('Make Up','Make Up'),
('Skin Care','Skin Care'),
('Fragrance','Fragrance'),
('Personal Care','Personal Care'),
('Hair Care','Hair Care'),
)
item_name = models.CharField(max_length=50,verbose_name='Product Name')
item_image = models.ImageField(verbose_name='Product Image')
item_thumb = models.ImageField(verbose_name='Product Thumb')
item_description = models.TextField(verbose_name='Product Descriptions')
item_mass = models.CharField(max_length=10,verbose_name='Product Weight')
item_category = models.CharField(max_length=20, choices = item_category_choices,verbose_name='Product Category')
item_sub_category = models.CharField(max_length=20,verbose_name='Product Sub Category')
item_est_price = models.DecimalField(max_digits=12,decimal_places=2,verbose_name='East Product Price')
item_wst_price = models.DecimalField(max_digits=12,decimal_places=2,verbose_name='West Product Price')
def __unicode__(self):
return (self.item_name)
def image_img(self):
if self.item_image:
return u'<img src="%s" width="50" height="50" />' % self.item_image.url
else:
return '(Sin imagen)'
image_img.short_description = 'Thumb'
image_img.allow_tags = True
Instead of submitting a link to a file "/home/prashant/Desktop/suede.png", you need to actually open the file and submit that instead.
For example, here is a test I have to test image submission:
# generate image and open
tmp_file = Image.new('RGB', (3, 3,), 'white')
tmp_file.putpixel((1, 1,), 0)
tmp_file.save(f.name, format='PNG')
_file = open(f.name, 'rb')
data = {'file': _file}
response = api.client.put(url=url, data=data)
You should open the image and send the request as follows:
with open("/home/prashant/Desktop/suede.png", 'rb') as image:
data = {'item_name': 'Lural',
'item_image': image,
'item_thumb': image,
'item_description': 'sd',
'item_mass': 1,
'item_category': 'Make Up',
'item_sub_category': 'Sub-Feminine',
'item_est_price': '123.12',
'item_wst_price': '120.34'
}
response = api.client.put(url, data, format='multipart')
This should work!

Categories

Resources