Quick reminder what is frisor
Frisor is a web application in Python/Django which is just a box for interesting urls. When using untrusted network I don’t want to login anywhere to save interesting content I found. More about this is here: Introduction to frisor.
This week I added a simple page on which we can see added urls and add url. Also, I introduced logging to my application.
My github repo: firsor repo.
Currently my application looks like this:
Templates in frisor with Django
Django templates are for creating web page html with dynamic content. Django uses its own template language called DTL(Django Template Language) which is quite similar to jinja. Anyway, it’s possible to change template engine, but I decided to use default one. Using templates is usually pretty straight-forward - at backend side create a context dictionary with names and values of variables which should be returned in response to fill dynamic parts of template. It’s a common practice to create template engines this way - the same method is used in Erlang’s ChicagoBoss and Zotonic frameworks or Ruby’s jekyll.
In Django you can set up location of your templates in settings.py
- default location is:
[app-dir]/templates/[name-of-app]/[name-of-template].html
. I decided to keep that as I want to see how defaults
are working in this framework.
My first template of index.html
page was about showing list of urls. It looked like this:
It uses context dictionary in backend views.py
which looks like:
After lunching my application I saw ugly html page, so it was time to make it look better. I’m really bad at designing frontend, so I decided to use bootstrap for styles - it’s simple and looks good without much effort. That’s really great that such things as forms and simple web pages can be created without any JavaScript. I’m considering using django-bootstrap library to not care about putting styles into my html code.
Currently frisor is a single page application and I would like to have the same header and footer for other pages.
It can be done with extend
tag in DTL.
How to put an external url in Django template
My first try with putting url into my template was like this - url.url
is a value of url
field of url
object.
Yeah, I should change name of my model to something else.
What’s an issue here?
When I put url: www.example.com
and clicked it I was redirected to http://localhost:8080/www.example.com
. It appears
that default redirecting is appending url to base server address.
Solution
To solve it I should append protocol prefix (http://
) if it’s not provided by user. I’ll do this on server side.
Using forms in Django
After fixing bad look of my urls table time had come to create a form to be able to add some urls to my application. To do this there are a few things needed:
Form in html file
On frontend side - form html with POST method (because it’s going to create a resource):
Nothing surprising here except {% csrf_token %}
tag. It’s for Cross Site Request Forgery
protection. CSRF attacks can occur when you have a session in web application and somebody will send you a malicious
website which will perform an action using your credentials and session in this application. Currently I don’t have
any sessions and users, but better to just add this tag now.
Handler for a POST request
On backend side - handler for a POST request:
I was wondering how to get to data sent by POST request. At first I tried request.body
, request.read
,
but it happens that Django puts all data into dictionary variable named as received request.
My form sends a POST request so dictionary at backend side is called POST and I can get to
field in data like this: request.POST['name_of_field']
.
Store url in database
In my model of Url
(in models.py
) I had to add a method for creating an url in database. Of course I could create an Url
object
using a constructor, but then I had to worry about putting unnecessary data like publish_date
, which should always
be set to current time when creating this object. My Url.create
method:
To create an Url
object in my view I had to do:
It’s obvious that save
method is needed to save an object in database. Create method doesn’t perform saving
and in my opinion it shouldn’t. Sometimes it’s needed to create a temporary object to do some actions using it
and after them throw it away. Saving logic should be extracted to some service - it shouldn’t be done in view.
But as I’m following KISS principle this can be done later.
How to display Django template code on my blog?
At my blog I’m using jekyll with liquid as template language. Actually liquid is quite similar
to jinja which is similar to DTL. So there was a funny issue with this. I wanted to display some of
my template code into this post on this blog.
At first it was quite surprising that when putting something like this into my posts markdown:
{{url.url}}
it actually became an empty string. It’s because jekyll is interpreting this
as liquids filter and url.url
is not defined so it becomes an empty string.
Solution
To be able use DTL code in my posts I’ve to use a special tag:
Logging
Default logging configuration added to Django doesn’t log to console anything except Django logs, so when you put something like this into your package:
and use it inside your packages as logger.info("Info log")
it will not display those logs in console after running
$ python manage.py runserver
.
Solution for this is adding custom logging configuration in settings.py
.
My logging configuration (see comments in a code):
My TODO list:
- Introduce unit tests.
- When creating append
http://
to url if it’s not there - someone told me that I can do this also withUrlField
- probably I should’ve read documentation more carefully. - Introduce
django-bootstrap
instead of currently usedbootstrap
to templates. - Introduce footers and headers in html pages.
- Introduce validation to url form.
- Add comments and tags to urls
- Refactor database logic from
views.py
to use someservice.py
Leave a Comment