Django community: Community blog posts RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
Django Settings Deployment
Learn how to deploy Django settings into environment independent such as development and production -
Building a multi-tenant web application with Django 1.9 framework(Part1)
In this tutorial we are going to build a multi tenant web application with Django 1.9 framework.Multi tenancy is used mainly for SAAS(Software As a Service) products.SAAS is a software delivery model used in the cloud where each customer gets only the service offered by a specific product not the product itself ,the customer gets a relatively isolated environment for its data which other customers don't have access to. Multitenancy can be achieved using 3 different techniques: Single web application instance and multiple database With this multitenancy technique, each customer gets his own database which offers the most secure environment for clients but also it is the most costly technique in term of servers resources. Single web application instance and multiple schemas With this multitenancy technique each client or tenant gets his own schema.Schemas are only available with Postgres database system. Single web application instance,one database and one schema With multitenancy technique tenants share the same database and the same schema ,the security and separation is handled only by application code.There is no real separation in client's data.This method is less secure but it takes less server resources. Multitenancy with Django and Postgres Each technique has its pros and cons.In … -
Building a multi-tenant web application with Django 1.9 framework(Part1)
In this tutorial we are going to build a multi tenant web application with Django 1.9 framework.Multi tenancy is used mainly for SAAS(Software As a Service) products.SAAS is a software delivery model used in the cloud where each customer gets only the service offered by a specific product not the product itself ,the customer gets a relatively isolated environment for its data which other customers don't have access to. Multitenancy can be achieved using 3 different techniques: Single web application instance and multiple database With this multitenancy technique, each customer gets his own database which offers the most secure environment for clients but also it is the most costly technique in term of servers resources. Single web application instance and multiple schemas With this multitenancy technique each client or tenant gets his own schema.Schemas are only available with Postgres database system. Single web application instance,one database and one schema With multitenancy technique tenants share the same database and the same schema ,the security and separation is handled only by application code.There is no real separation in client's data.This method is less secure but it takes less server resources. Multitenancy with Django and Postgres Each technique has its pros and cons.In … -
How to Create a Password Reset View
For this short tutorial we will be using the django.contrib.auth views to add a password reset functionality to your Django application. The process of reseting passwords involves sending emails. For that matter we will be using console email backend to debug and check if everything is working. In the end of this tutorial I will also provide resources to properly configure a prodution-quality email server. Dependencies Basically all you need is to have django.contrib.auth in your INSTALLED_APPS and a email service properly configurated (for production). During the development we can use file/console email backend. settings.py INSTALLED_APPS = [ ... 'django.contrib.auth', ] EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # During development only Implementing We need 4 different views: password_reset: Form where the user submit the email address password_reset_done: Page displayed to the user after submitting the email form. Usually with instructions to open the email account, look in the spam folder etc. And asking for the user to click on the link he will receive. password_reset_confirm: The link that was emailed to the user. This view will validate the token and display a password form if the token is valid or an error message if the token is invalid (e.g. was already used or … -
Caktus Group @ PyData Carolinas 2016
Tomorrow marks the official beginning of PyData Carolinas 2016 (though technically, the tutorials started today). This is the first time PyData has hosted a conference in our area. We’re especially proud of the way local leaders and members of meetups like TriPython, TechGirlz, Girl Develop It RDU, and PyLadies have worked in tandem to put this event together for the Python community. Caktus will be at PyData tomorrow and Friday as a Silver sponsor. We’re glad to be in the company of esteemed sponsoring organizations like IBM, RENCI, Continuum Analytics, and the Python Software Foundation. Come see us at the following PyData events and talks! Wednesday, September 14th 7:00PM - 8:00PM Evening Social at the 21c Museum Hotel Join us after the tutorials with a social hosted by the Durham Convention Center. More details here. Thursday, September 15th 8:30AM - 5:30PM Caktus Booth We’ll have a booth with giveaways for everyone plus a raffle. We’ll also have a display of OpenDataPolicingNC, a project Caktus CTO Colin Copeland helped lead; it received a White House nod for Code for Durham. 11:30AM - 12:10PM Reach More People: SMS Data Collection with RapidPro (Room 1) Erin Mullaney (Caktus) and Rebecca Muraya (TransLoc) will … -
Performing Maintenance on Pods
Kubernetes includes a feature called services which serve as a kind of load balancer for pods. When pods misbehave or otherwise stop working, sometimes you'll want to remove the pod from the service without killing the pod. ## Services & Endpoints Each service has a list of endpoints for the service which correspond to the pods for that service. This list of endpoints is updated automatically with the IPs and ports for the pods based on a label selector defined on the service. This allows the service to be loosely coupled to the pods themselves. You can see the selector pattern used in [...] -
Django Shortcuts
This module is a collection of helper classes generally used in view functions/classes. All the shortcuts are available in the module django.shortcuts. render Params: def render(request, template_name, context=None, content_type=None, status=None, using=None) Shortcut for: content = loader.render_to_string(template_name, context, request, using=using) return HttpResponse(content, content_type, status) There is also render_to_response, the only difference is that it does not pass the request to the context. redirect Params: def redirect(to, *args, **kwargs): Returns an HttpResponseRedirect (or HttpResponsePermanentRedirect) to the appropriate URL for the arguments passed. The arguments could be: A model: the model’s get_absolute_url() function will be called. A view name, possibly with arguments: urls.reverse() will be used to reverse-resolve the name. A URL, which will be used as-is for the redirect location. Shortcut for: def post_view(request, post_id): post = Post.objects.get(pk=post_id) return redirect(post) # equivalent to: return HttpResponseRedirect(post.get_absolute_url()) def post_view(request, post_id): return redirect('post_details', id=post_id) # equivalent to: return HttpResponseRedirect(reverse('post_details', args=(post_id, ))) def relative_url_view(request): return redirect('/posts/archive/') # equivalent to: return HttpResponseRedirect('/posts/archive/') def absolute_url_view(request): return redirect('https://simpleblog.com/posts/archive/') # equivalent to: return HttpResponseRedirect('https://simpleblog.com/posts/archive/') See more in this post about the redirect function. get_object_or_404 Params: def get_object_or_404(klass, *args, **kwargs): Shortcut for: try: return Model.objects.get(pk=1) except Model.DoesNotExist: raise Http404() get_list_or_404 Params: def get_list_or_404(klass, *args, **kwargs): Shortcut for: obj_list = list(Model.objects.filter(title='test')) if … -
Watermarking images on Django sites
Have you ever noticed how stock photography sites add watermarks to the images shown on their catalogs? They do that to make sure people don’t just take the free samples and use them without proper licensing. Google Maps does it for the satellite imagery as well. Turns out this is pretty easy to do and we’ll show you how to do it for Django sites sites using Pillow and django-imagekit. All the code is available on GitHub and a Vagrantfile is provided if you want to try the live Django demo by yourself. Watermarking images First we’ll show you three simple watermarking techniques that can be used in an Python project that uses images, and then we’ll use what we’ve built to add watermarks to images on a sample Django site. Text overlay The first thing we’ll do is add a semi-transparent text legend on the center of an image. We’ll use Pillow’s Image, ImageDraw and ImageFont modules. The following function adds a text overlay on the center of the supplied image: # processors.py from PIL import Image, ImageDraw, ImageFont _default_font = ImageFont.truetype('/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf', 24) def add_text_overlay(image, text, font=_default_font): rgba_image = image.convert('RGBA') text_overlay = Image.new('RGBA', rgba_image.size, (255, 255, 255, 0)) image_draw … -
A Brief Introduction to Django Channels
Django has long been an excellent web framework. It has helped many developers and numerous businesses succeed over the years. But before the introduction of Channels, Django only supported the http protocol well. With the gradual evolution of the web technologies, standing here in 2016, supporting http only is simply not enough. Today, we are using websockets for real time communications, WebRTC is getting popular for real time collaboration or video calling, HTTP/2 is also being adapted by many. In the current state of the web, any modern web framework needs to be able to support more and more protocols. This is where Django Channels come into play. Channels aim at adding new capabilities to Django, including the support for modern web technologies like websockets or http2. How does “Channels” work? The idea behind Channels is quite simple. To understand the concept, let’s first walk through an example scenario, let’s see how Channels would process a request. A http/websocket request hits the reverse proxy (ie, nginx). This step is not compulsory but we’re conscious developers and always make sure our requests first go through a hardened, battle proven reverse proxy before it hits our application server Nginx passes the request … -
Testing dates in Django
Django makes unit & functional testing easy (especially with WebTest). Tests on routing, permissions, database updates and emails are all straightforward to implement but how do you test dates & time? You might for example want to test regular email notifications. -
Testing dates in Django
Django makes unit & functional testing easy (especially with WebTest). Tests on routing, permissions, database updates and emails are all straightforward to implement but how do you test dates & time? You might for example want to test regular email notifications. -
Fixing "Symbol not found: _PyUnicodeUCS2_Compare and _PyUnicodeUCS2_AsASCIIString"
I've got a new client with a legacy Django project running on Python 2.7 with Pandas. When I was configuring my local OS X environment I got a bunch of nasty errors: ImportError: dlopen(/Users/mike/.pyenv/versions/project/lib/python2.7/site-packages/pandas/hashtable.so, 2): Symbol not found: _PyUnicodeUCS2_Compare Referenced from: /Users/mike/.pyenv/versions/project/lib/python2.7/site-packages/pandas/hashtable.so Expected in: flat namespace in /Users/mike/.pyenv/versions/project/lib/python2.7/site-packages/pandas/hashtable.so My first assumption was to upgrade Pandas from 0.15.1 to the most recent 0.18.1, but that didn't help. I rolled back to Pandas 0.15.1 to avoid any possible regressions. After tens minutes of reading traceback messages and googling, I managed to fix that error with running $ pip install -U cython. After that I've got: ImportError: dlopen(/Users/mike/.pyenv/versions/2.7.12/envs/project/lib/python2.7/site-packages/numpy/core/multiarray.so, 2): Symbol not found: _PyUnicodeUCS2_AsASCIIString Referenced from: /Users/mike/.pyenv/versions/2.7.12/envs/project/lib/python2.7/site-packages/numpy/core/multiarray.so Expected in: flat namespace in /Users/mike/.pyenv/versions/2.7.12/envs/project/lib/python2.7/site-packages/numpy/core/multiarray.so It seemed to be fixed in the most recent Numpy version, so I ran $ pip install -U numpy pandas, and the error disappeared. I hope this short blog post will save your time. You're welcome to share your experience with fixing similar not obvious issues. -
How to create thumbnail image in Django templates using sorl-thumbnail?
Sorl thumbnail is the package which is being widely used to generate thumbnail in Django. It will create a thumbnail of given size for the given image. The following is a sample code to create the thumbnail in Django template. {% thumbnail item.image "100x100" as im %} <img src="{{ im.url }}"> {% endthumbnail %} The above syntax will create a thumbnail in cache folder of your folder structure. But the only problem with this is, the thumbnail won’t be consistent for the responsive designs. For example, if we create a thumbnail of size 100x100, if the responsive blocks for the thumbnail are of various sizes like 100x100, 200x250 and 50x50, then the thumbnail generated will be apt for the screens which are of size 100x100 but when it comes to other two screens the thumbnail will get compressed or stretched. srcset: Html5 has a solution for the above problem in terms of images. Html5’s srcset attribute of image tag(<img>) is the appropriate solution for the above problem. Here is an example of how to use ‘srcset’ attribute. Suppose we want a different size (height, width) image on a larger or smaller viewport. Consider this example: <img src="images/image1.jpg" srcset="images/image1.jpg … -
Django Tips #14 Using the Messages Framework
Keeping the users of your application aware of what is going on makes a huge difference in the user experience. If there is something users hate more than slow applications, it is applications that does not communicate with them. – The user clicks in a save button. – Nothing happens. – So, did it save the data or not? – User reaction after a couple of (mili)seconds: *Click!* *Click!* *Click!* *Click!* Let’s make our users more confident and comfortable, shall we? Configuration By default, a brand new Django project already comes with the messages framework installed. If you did not change anything in relation to the messages framework, just skip to the next section. Otherwise, set it up: INSTALLED_APPS django.contrib.messages MIDDLEWARE or MIDDLEWARE_CLASSES in older versions: django.contrib.sessions.middleware.SessionMiddleware django.contrib.messages.middleware.MessageMiddleware TEMPLATES context_processors django.contrib.messages.context_processors.messages Message Levels and Tags Constant Level Tag (for CSS) Purpose DEBUG 10 debug Development-related messages that will be ignored (or removed) in a production deployment INFO 20 info Informational messages for the user SUCCESS 25 success An action was successful WARNING 30 warning A failure did not occur but may be imminent ERROR 40 error An action was not successful or some other failure occurred By default, Django will … -
How to create Periodic Tasks with Django Celery?
Celery provides asynchronous job queues, which allows you to run Python functions in the background. Celery is on the Python Package Index (PyPi), and can be easily installed with pip or easy_install and its dependencies. Installation: $ pip install django-celery && pip install redis Celery uses a broker to pass messages between your application and Celery worker processes. We are having like rabbitmq, redis but we are using redis as a broker in this article. To initiate a task, an application will adds a message to the queue, which the broker then delivers to a worker. So we can install redis using the following command:; sudo apt-get install redis-server Setting up celery in your project: 1. We need to add 'djcelery' into your project Installed Apps. INSTALLED_APPS += ( 'djcelery', ) 2. To configure celery, we are using redis broker which is easy to install, lightweight, fast: import djcelery djcelery.setup_loader() BROKER_URL = 'redis://localhost:6379/1' 3. We should specify imports i.e from where tasks are being loaded using CELERY_IMPORTS command in settings.py file CELERY_IMPORTS = ("testapp.tasks") 4. Celery Periodic Task means which runs at a regular intervals of time. These periodic tasks are … -
Best Practices of Using Django Celery in Django Social Auth
Introduction to 'Celery': In development environment sometimes we need to execute some works asynchronously(irrespective of current program flow). For example, in real time development we may have to send emails to 1000 members. Let us suppose if the time required to send single mail is 1 sec then it will take 1000 secs to send emails to 1000 persons, here the program flow will halt for 1000 seconds, which is a bad experience for the user. 'Celery' is an asynchronous task queue which is written in python provides to run the tasks asynchronously irrespective of current program flow. Celery communicates via messages, usually using a broker to mediate between clients and workers. To initiate a task a client puts a message on the queue, the broker then delivers the message to a worker. Problems over 3rd party interface integration: Generally, social networks are 3rd party interfaces which are hard to integrate with. These may lead to some problems as following. Speed. Much slower than local data. Users may still expect near-immediate results. Rate limits. Different rules for every service. Need to handle reactive & proactive as some don't publish rates. Instability. Outages (there is a chance of third party servers does … -
Handling Custom Error Pages(404, 500) In Django
404 Page not found and 500 Internal server errors generally occur on every website. When these errors occur, generally for Django application it will load a page showing the application settings. So to avoid settings open, we'll keep DEBUG=False in production mode. Nginx or apace by default serve 404 and 500 pages when DEBUG=False, which are not user-friendly. So in order to display better-looking UI to the end user, we'll customize the Django's built-in 404 and 500 pages. By default, these error pages are handled by handlerxxx views. For example 404 errors will be served by handler404 view, similarly, 500 Internal server error will be handled by handler500. So in order to display our custom pages instead of web server's pages, we will override the Django's handlerxxx views. In your views.py def handler404(request): return render(request, '404.html', status=404) def handler500(request): return render(request, '500.html', status=500) Now just specify these in your urls.py as below. handler404 = myapp.views.handler404 handler500 = myapp.views.handler500 In settings.py You need to add your hostname in ALLOWED_HOSTS like: ALLOWED_HOSTS = ['testsite.com', 'localhost'] With the above steps, we'll get to see your own custom error pages served by Django's views with better UI. -
Deploying Django with Gunicorn and Supervisor
Here in Monmar we deploy all Django applications with Gunicorn and Supervisor. I personally prefer Gunicorn to uWSGI because it has better configuration options and more predictable performance. In this article we will be deploying a typical Django application. We won't be using async workers because we're just serving HTML and there are no heavy-lifting task in background. I'm assuming that our Django project was created with Cookiecutter Django, an awesome boilerplate developer by Daniel Roy Greenfeld. I strongly recommend using it for every new Django project. Our requirements/production.txt file should already contain these two packages: # WSGI Handler # ------------------------------------------------ gevent==1.1.1 gunicorn==19.6.0 So, we only need to SSH to the server, create a virtualenv and populate it with packages: $ virtualenv --python=python3.5 .venv $ source .venv/bin/activate $ pip3 install -r requirements.txt Next, we're going to add missing configs to our working copy: $ mkdir -p deploy/production && cd deploy/production $ touch gunicorn.conf.py nginx.conf run.sh supervisor.conf I'm providing real configuration files we're using for our company website. So, please update it for your project needs. gunicorn.conf.py bind = 'unix:/tmp/gunicorn-monmar.sock' workers = 2 timeout = 30 nginx.conf upstream monmar { server unix:/tmp/gunicorn-monmar.sock fail_timeout=0; keepalive 60; } server { listen 80; listen … -
How to Work With AJAX Request With Django
There are many scenarios where you may want to use AJAX requests in your web application. It is a great resource that enables web applications to be faster and more dynamic. For this short tutorial I will be using jQuery to ease the implementation. You can choose a different framework, or even implement it using JavaScript only. But the concept will remain the same. Initial Setup Here is how my base.html template looks like: {% load static %}<!doctype html> <html> <head> <meta charset="utf-8"> <title>{% block title %}Default Title{% endblock %}</title> <link rel="stylesheet" type="text/css" href="{% static 'css/app.css' %}"> {% block stylesheet %}{% endblock %} </head> <body> <header> ... </header> <main> {% block content %} {% endblock %} </main> <footer> ... </footer> <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script> <script src="{% static 'js/app.js' %}"></script> {% block javascript %}{% endblock %} </body> </html> The jQuery library and all the JavaScript resources stays in the end of the HTML page for two reasons: to guarantee the DOM will be loaded whe the script is executed and to avoid inline scripts (at least scripts that uses jQuery). All the extra or page specific JavaScript goes inside the {% block javascript %}{% endblock %} block. Sample Scenario Let’s say you want … -
Django to Ember #1
If you know Django and want to learn Ember (or vice-versa), this guide is for you. To get started, let's see what happens when a user opens the `/contact` page in both frameworks. -
Django to Ember #1
If you know Django and want to learn Ember (or vice-versa), this guide is for you. To get started, let's see what happens when a user opens the `/contact` page in both frameworks. -
Simple qgis plugin repo
At my company, we sometimes build QGIS plugins. You can install those by hand by unzipping a zipfile in the correct directory, but there's a nicer way. You can add custom plugin "registries" to QGIS and QGIS will then treat your plugins just like regular ones. Here's an example registry: https://plugins.lizard.net/ . Simple, right? Just a directory on our webserver. The URL you have to configure inside QGIS as registry is that of the plugins.xml file: https://plugins.lizard.net/plugins.xml . The plugins.xml has a specific format: <?xml version="1.0"?> <plugins> <pyqgis_plugin name="GGMN lizard integration" version="1.6"> <description>Download GGMN data from lizard, interpolate and add new points</description> <homepage>https://github.com/nens/ggmn-qgis</homepage> <qgis_minimum_version>2.8</qgis_minimum_version> <file_name>LizardDownloader.1.6.zip</file_name> <author_name>Reinout van Rees, Nelen &amp; Schuurmans</author_name> <download_url>https://plugins.lizard.net/LizardDownloader.1.6.zip</download_url> </pyqgis_plugin> .... more plugins ... </plugins> As you see, the format is reasonably simple. There's one directory on the webserver that I "scp" the zipfiles with the plugins to. I then run this script on the directory. That script extracts the (mandatory) metadata.txt from all zipfiles and creates a plugins.xml file out of it. A gotcha regarding the zipfiles: they should contain the version number, but, in contrast to python packages, the version should be prefixed by a dot instead of a dash. So no myplugin-1.0.zip but myplugin.1.0.zip. … -
How to Create a One Time Link
Django uses a very interesting approach to generate the Password reset tokens. I’m not really a security expert, neither I’m very familiar with cryptography algorithms, but it is very safe and reliable. Before I elaborate a little be more on the one-time-link generation, I wanted to discuss about the Django’s PasswordResetTokenGenerator implementation. Because what we will be doing is actually extending this particular class to fit our needs. Generally speaking, Django generate a token without persisting it in the database. Yet, it still have the capabilities of determining whether a given token is valid or not. Also the token is only valid for a defined number of days. The default value for the Password Reset Token is 7 days, and it can be changed in the settings.py by changing the value of PASSWORD_RESET_TIMEOUT_DAYS. The class have two public methods: make_token(user) check_token(user, token) The make_token method will generate a hash value with user related data that will change after the password reset. Meaning, after the user clicks on the link with the hash and proceed to the password reset, the link (or the hash) will no longer be valid: def _make_hash_value(self, user, timestamp): # Ensure results are consistent across DB backends … -
Django Tips #13 Using F() Expressions
In the Django QuerySet API, F() expressions are used to refer to model field values directly in the database. Let’s say you have a Product class with a price field, and you want to increase the price of all products in 20%. A possible solution would be: products = Product.objects.all() for product in products: product.price *= 1.2 product.save() Instead you could use an F() expression to update it in a single query: from django.db.models import F Product.objects.update(price=F('price') * 1.2) You can also do it for a single object: product = Product.objects.get(pk=5009) product.price = F('price') * 1.2 product.save() But take care with this kind of assignment. The F() object persist after saving the model. product.price # price = Decimal('10.00') product.price = F('price') + 1 product.save() # price = Decimal('11.00') product.name = 'What the F()' product.save() # price = Decimal('12.00') So, basically after updating a field like that, product.price will hold an instance of django.db.models.expressions.CombinedExpression, instead of the actual result. If you want to access the result immediately: product.price = F('price') + 1 product.save() print(product.price) # <CombinedExpression: F(price) + Value(1)> product.refresh_from_db() print(product.price) # Decimal('13.00') You can also use it to annotate data: from django.db.models import ExpressionWrapper, DecimalField Product.objects.all().annotate( value_in_stock=ExpressionWrapper( F('price') * F('stock'), … -
Dealing With QueryString Parameters
It is kinda tough to describe what the problem really is. But, do you know when you are creating an interface where you provide pagination, filters and ordering, and you are making it controlling it via URL Get parameters? For instance if you have different options for ordering, you might think of something like that: <div class="dropdown"> <button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown"> Order by </button> <ul class="dropdown-menu"> <li><a href="?order=name">Name (a-z)</a></li> <li><a href="?order=-name">Name (z-a)</a></li> <li><a href="?order=price">Price</a></li> <li><a href="?order=date">Date</a></li> </ul> </div> Basically you would be sending the user to the very same page, but passing a GET parameter named order, where you could do something like that: def products_list(request): products = Product.objects.all() order = request.GET.get('order', 'name') # Set 'name' as a default value products = products.order_by(order) return render(request, 'products_list.html', { 'products': products }) PS: This is a minimalist example, if you pass an invalid parameter directly in the querystring you will make queryset break. I will avoid adding extra validations so we can focus on the objective of this article. So far so good. But the problem starts to appear when you add new control, also via GET parameter. Lets say a pagination: <ul class="pagination"> {% for i in page_obj.paginator.page_range %} …