I have written some code in Python that reads in two strings, removes the punctuation and then compares the words in them within a matrix table which it prints to the console.
How do I convert the code to be utilised within the Django framework. I want to display a similar matrix on the web. I've already imported it into views. Please may someone point me in the right direction? I've been using django project and lynda to learn as I go along,
Edit:
Merci for the help guys. Managed to get it to display on a webpage. But it is printing it all out as a single string. How do I style it a bit better?
Think of passing your data to a "Django webpage" as just passing a dictionary of your values to a Django template from your Django view.
What is a Django template?
A Django template is the 'T' in Django's 'MTV' design pattern. In the conventional MVC design pattern (Model-View-Controller), the View is where you display things. In Django, Templates are where you display things. Oddly enough, the 'View' in Django is actually the Controller. This took me a while to wrap my head around.
Why do we use a dictionary-like context?
By mapping keys to values we achieve super-fast [O(1)/constant] lookup in the Django templates.
With all of this in mind, I'd advocate using 'TemplateView' generic view, doing your work in a utils file, importing utils into views, and then passing your data to the template via the context dictionary. So it would look something like this:
local_utils.py
import string
import pandas as pd
pd.set_option('display.max_columns', None)
def generate_out_matrix():
with open('./arrayattempts/samp.txt', 'r') as file1:
sampInput=file1.read().replace('\n', '')
#print(sampInput)
with open('./arrayattempts/ref.txt', 'r') as file2:
refInput=file2.read().replace('\n', '')
#print(refInput)
sampArray = [word.strip(string.punctuation) for word in sampInput.split()]
refArray = [word.strip(string.punctuation) for word in refInput.split()]
out=pd.DataFrame(index=refArray,columns=sampArray)
for i in range(0, out.shape[0]):
for word in sampArray:
out.ix[i,str(word)] = out.index[i].count(str(word))
return out.as_matrix()
views.py
from appname.local_utils import generate_out_matrix
class Detail(TemplateView):
template_name = 'appname/yourhtml.html'
# Will render on each call to URL for 'Detail'
def get_context_data(self):
out = generate_out_matrix()
context['out'] = out
return context
appname/templates/yourhtml.html
{% if out %}
{% for row in out_matrix %}
{% for o in row %}
{{ o }}
{% endfor %}
<br>
{% endfor %}
{% endif %}
urls.py
path('/your_path', views.Detail.as_view()),
https://docs.djangoproject.com/en/2.0/ref/templates/api/#rendering-a-context
To send your data to your template you should add your variable to context at your views
from django.http import Http404
from django.shortcuts import render
from polls.models import Poll
def detail(request, poll_id):
... // your logic
out // your variable
return render(request, 'yourhtml.html', {'out': out})
In html will be like that
{{ out }}
{% for o in out %}
{{ o }}
{% endfor %}
https://docs.djangoproject.com/en/2.0/topics/http/views/
You can style your table with some CSS or using ny lib struct to handle tables
You can follow this guide
display django-pandas dataframe in a django template
Related
I need to apply a if statement in template file based on response code with respect to a url. As I'm not aware of any direct method, I'm planning to make a custom template tag like:
from django import template
register = template.Library()
#register.filter(name='code')
def code(url):
a = http.response(url)
return a
I will then call this within the template as:
{% if model.fileurl|code==200 %}
<div>..............</div>
Also, is there any way to do it directly within the template as I'm trying to fill in the shoes of our django developer.
You can make a template tag that returns the status code:
# app/templatetags/code.py
from django import template
from requests import get as reqget
register = template.Library()
#register.filter(name='code')
def code(url):
reqget(url).status_code
The app/templatetags/ directory need to contain an __init__.py file as well (if this is not the case yet, you can add an empty one).
and then in the template:
{% load code %}
{% if model.fileurl|code == 200 %}
<div>..............</div>
{% endif %}
I am new to Django and trying to grasp why or how to mitigate the extra <li> and have not found anything yet. Here is an image of what the output is doing.
EDIT: I have tried cleaning the string as suggested below and still no luck. This happens even when I ran through the Django Tutorial. I know I can use JS or JQuery to remove them, however being as basic as this is, and knowing there are ONLY 2 objects for the model, I would like to know why it inserts this additional
And here is a snippet of my template:
{% extends "base_templates/stations.html" %}
{% block station_content %}
<h2>Stations</h2>
<ul>
{% for station in object_list %}
{% if station.name.strip != "" %}
<li>{{ station.name }}<li>
{% endif %}
{% endfor %}
</ul>
{% endblock %}
EDIT: Here is my view for this template as well
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views import generic
from django.views.generic import ListView
from django.utils import timezone
from .models import Customer, CustomerContact, Station, SubcontractorContact
# Create your views here.
class CustomerView(ListView):
model = Customer
class StationView(ListView):
model = Station
If you just check it for being empty, it might not validate for white space. Trim the string before you check it for being empty as " " and "" are not equal
Try:
if(station.name.strip()!="")
Okay, THANK YOU so much everyone who contributed... HOWEVER if we take a look at that wonderful closing <li> we see well theres no /... So once again thank you everyone, have a wonderful day!
I use the same models in many different templates and tables. I'm looking for a way to tell Django how to render those objects in templates so I don't have to write the same html again and again.
For example model Url - when I want to display it inside a template or table, I have to write (sometimes much more):
{{ url.site.name }}
which renders:
Stackoverflow.com
It would be better if I could just do something like:
{{ url }} # url is Url model object
I think that I can add methods like def render_object(self) like this:
def render_object(self):
return mark_safe("""{}""".format(self.url,self.site.name))
and in templates:
{{ url.render_object }}
but I'm curious if it is there some built in function. As far as I know __unicode__(self) would do the work but it would mess admin and shell display names.
Add custom template tag my_tags.py like render_url and then in your template load that template tag ({% load my_tags %}) and send url object to it: {% render_url url %}. You can use html template in your tag or just make result as a string and return it. Check the documentation for details.
I have created a template tag and trying to loop through the results from the template tag
but I don't get any results
tags.py
from django import template
from loadprograms import dbcontext
register = template.Library()
#register.simple_tag
def get_category():
x = dbcontext.DBContext()
results = x.executequery("Select name from Categories")
categories = [each[0] for each in results]
return categories
template code
{% load category_tags %}
{% get_category %}
{% for each in get_category %}
{{ each }}
{% endfor %}
The {% get_category %} prints all the categories without any issues but the for loop stmt
that loop through the results does not work
What could be the problem?
To make this change in your tag, you'll have to set a variable in the context, but if your objective is to have a list of categories available in templates, just like you would have passed it in from the view - then you need to write a template context processor, which will allow all views to have this variable in their context.
A template context processor is just a method that adds to the request context, by returning a dictionary. Think of it like a view function, that just returns a context.
from .models import Categories
def cat_names(request):
return {'category_names': Category.objects.values_list('name', flat=True)}
To activate this context processor, you have to do a few things:
Add the above code to a file called template_processors.py in the same place as your models.py and views.py.
In your settings.py, add the fully-qualified name of the method to the TEMPLATE_CONTEXT_PROCESSORS setting, making sure you don't override the defaults. To do this easily, import the default settings first, then add to it:
from django.conf.default_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP
TEMPLATE_CONTEXT_PROCESSORS = TCP + ('yourapp.template_processors.cat_names',)
Use the render shortcut, which will make sure the context is correctly passed.
In your views, you can now just do this:
from django.shortcuts import render
def home(request):
return render(request, 'home.html')
In your home.html, you can now do:
{% for name in category_names %}
{{ name }}
{% endfor %}
This is a snippet of my code.
soup=BeautifulSoup(html_document)
tabulka=soup.find("table",width="100%")
dls=tabulka.findAll("dl",{"class":"resultClassify"})
tps=tabulka.findAll("div",{"class":"pageT clearfix"})
return render_to_response('result.html',{'search_key':search_key,'turnpages
':tps,'bookmarks':dls})
I checked the dls, it is a dict contains only one html label
<dl>label contents contains some <dd> labels</dl>
But after pass dls to render_to_response the result is not correct.
The corresponding template code in result.html is:
{% if bookmarks %}
{% for bookmark in bookmarks %}
{{bookmark|safe}}
{% endfor %}
{% else %}
<p>No bookmarks found.</p>
{% endif %}
The output result html contains a python dictionary format like this:
[<dd>some html</dd>,<dd>some html</dd>,<dd>some html</dd>,...]
This appears in the output html. That is very strange. Is this a bug of renfer_to_response?
Well, dls is a python list containing the text of all the matching elements. render_to_response doesn't know what to do with a list, so it just turns it into a string. If you want to insert all the elements as HTML, try joining them into a single piece of text like so:
dls = "".join(dls)
Note that by doing so you are pasting live HTML from some other source into your own page, which is potentially unsafe. (What happens if one of the dds contains malicious Javascript? Do you trust the provider of that HTML?)
You have to use a RequestContext instance when rendering templates in Django.
say like this
return render_to_response('login.html',{'at':at}, context_instance = RequestContext(request))
for this to use, you need to import as follows:
from django.template import RequestContext
Hope this works for you. :)