Django community: RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
Authenticating via JWT using Django, Axios, and Vue
Getting Django Rest Framework, JWT, Axios, and Vue.js to play nice isn't easy. Here's my quick-and-dirty cheatsheet that I wrote while glueing the pieces together. Note: My architecture doesn't use django-webpack-loader. Instead, I'm running Django and Vue.js as two separate projects. I do this because I much prefer generating new projects with vue create over configuring webpack. The Back-End First, install some Django parts using the installer of your choice: pip install Django pip install djangorestframework pip install django-cors-headers pip install djangorestframework-jwt Then, configure Django in settings.py: INSTALLED_APPS = ( ... 'rest_framework', 'rest_framework.authtoken', 'rest_framework.authtoken', 'corsheaders', ) MIDDLEWARE_CLASSES = ( ... 'corsheaders.middleware.CorsMiddleware', ) CORS_ORIGIN_ALLOW_ALL = False CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_WHITELIST = ( # TODO - set this properly for production 'http://127.0.0.1:8080', 'http://127.0.0.1:8000', ) REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': ( # By default we set everything to admin, # then open endpoints on a case-by-case basis 'rest_framework.permissions.IsAdminUser', ), 'TEST_REQUEST_RENDERER_CLASSES': ( 'rest_framework.renderers.MultiPartRenderer', 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.TemplateHTMLRenderer' ), 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', ), 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 'PAGE_SIZE': 20, } from datetime import timedelta JWT_AUTH = { 'JWT_ALLOW_REFRESH': True, 'JWT_EXPIRATION_DELTA': timedelta(hours=1), 'JWT_REFRESH_EXPIRATION_DELTA': timedelta(days=7), } Once that's done, it's time to do modify the urls.py: from django.conf.urls import include, url ... urlpatterns = [ ... # JWT auth url(r'^api/v1/auth/obtain_token/', obtain_jwt_token), … -
The final INTERNAL_IPS fix for development hosts
The final INTERNAL_IPS fix for development hosts Django’s INTERNAL_IPS setting is an ongoing source of frustration and confusion (not only, but also) for users of django-debug-toolbar, especially when using non-local addresses. This is very useful for testing a website using mobile devices if you do not have a very fast internet connection where it does not matter whether you connect to a host through the local network or via the internet, for example using localtunnel. For some time we had a utility function which automatically added all detected network interface IPs to INTERNAL_IPS. However, this does not work when using virtualization software such as Docker or Vagrant with port forwarding, because the VM’s (or container’s) IP isn’t what you want – you want the host IP. Once I took a step back I saw a different, but much simpler solution. INTERNAL_IPS can be replaced with an object which simply answers True to all __contains__-type questions: if DEBUG: # `debug` is only True in templates if the vistor IP is in INTERNAL_IPS. INTERNAL_IPS = type(str('c'), (), {'__contains__': lambda *a: True})() -
PyCon IT 2018 “Nove”
PyCon Italia is the national conference where professionals, researchers and enthusiasts of the most beautiful programming language gather together. -
How to Apply Image Filters in OpenCV with Python
Add your own image filters on ... -
Goodbye manage.py
Every Django project starts with a manage.py file in its root. It's a convenience script that allows you to run administrative tasks like Django's included django-admin. In our last post, we discussed the merits of including a setup.py file in your project to make it installable as a true Python package. We'll build on that and show you how to properly setup a console script in the package. Hello Entry Points The setup function provided by setuptools accepts an entry_points keyword argument that is used to dynamically create scripts from a provided Python function on install. If we crack open the existing manage.py and strip it down to its essentials, we can see it isn't really doing much: import os import sys os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") from django.core.management import execute_from_command_line execute_from_command_line(sys.argv) It sets a default environment variable and then calls a function passing in the provided command line arguments. This can easily be turned into an entry point by simply making it a function inside our project. I typically add it to myproject/__init__.py like so: import os import sys def manage(): os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") from django.core.management import execute_from_command_line execute_from_command_line(sys.argv) Now we adjust our setup.py to add the entry point: setup( ... entry_points={'console_scripts': [ … -
Goodbye manage.py
Every Django project starts with a manage.py file in its root. It's a convenience script that allows you to run administrative tasks like Django's included django-admin. In our last post, we discussed the merits of including a setup.py file in your project to make it installable as a true Python package. We'll build on that and show you how to properly setup a console script in the package. Hello Entry Points The setup function provided by setuptools accepts an entry_points keyword argument that is used to dynamically create scripts from a provided Python function on install. If we crack open the existing manage.py and strip it down to its essentials, we can see it isn't really doing much: python import os import sys os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") from django.core.management import execute_from_command_line execute_from_command_line(sys.argv) It sets a default environment variable and then calls a function passing in the provided command line arguments. This can easily be turned into an entry point by simply making it a function inside our project. I typically add it to myproject/__init__.py like so: python import os import sys def manage(): os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") from django.core.management import execute_from_command_line execute_from_command_line(sys.argv) Now we adjust our setup.py to add the entry point: python setup( … -
Django - Referencing the User Model
There are 3 different ways to refer to the User model in Django. This post explains the differences and which approach to use. -
Offline messages for Django
Offline messages for Django django.contrib.messages is awesome. Its API surface is small, it’s fast and it does what it does really well. However, it sometimes happens that you would want to send messages to users outside the request-response cycle, for example from a background process or even from a post_save signal handler. Adding a full-blown notifications-and-messages-system is of course possible. Sending a one-off message to the user would be sufficient though, but there is no way to do this with Django’s messages framework. There are a few packages around solving this particular problem. Almost all of them solve this by saving undelivered messages in the database. My solution, django-user-messages follows the same approach, but contrary to many others it does not reimplement the message storage nor replace any other functionality of django.contrib.messages. It only adds a few additional utilities for adding messages (e.g. user_messages.api.info(...) instead of messages.info(...)) and a context processor which concatenates Django’s messages with those provided by django-user-messages. Instead of passing the request to messages.info(...) you would pass a user instance, or even only a user ID to api.info(...). Easy enough, and works well. Despite the 0.5 version number the package has been stable and essentially unchanged since … -
3rd Party Haar Cascades in OpenCV
Building on [face recognition ... -
How to add a watermark with overlays using OpenCV & Python
Creating a watermark with Open... -
Demystifying encodings — part 3
Do you ever have trouble with encodings? I used to in the past, but now I rarely do, because I do a simple thing. While knowing the things I explained in part 1 and part 2 of this series is necessary, otherwise I wouldn’t be able to fix problems, such problems rarely arise, because the first thing I do when I setup a GNU/Linux machine is set the system locale to UTF-8. The “locale” is the regional settings, among which the character encoding used. The procedure to set it up is this: Open the file /etc/locale.gen in an editor and make sure the line that begins with “en_US.UTF-8” is uncommented. Enter the command locale-gen; this will (re)generate the locales. Open the file /etc/default/locale in an editor, and make sure it contains the line LANG=en_US.UTF-8. Changes in this file require logout and login to take effect. Let me now explain what all this is about. The locale consists of a language, a country, and a character encoding; “en_US.UTF-8” means English, United States, UTF-8. This tells programs to show messages in American English; to format items such as dates in the way it’s done in the United States; and to use encoding … -
OpenCV & Python: Face Recognition and Identification
I'm really starting to enjoy w... -
Save an Auto Generated PDF File to Django model
To save a auto-generated PDF f... -
For hire
Since a slightly-wider circle of people know this now, it’s time to just go public with the news: my last day at now-former employer was toward the end of January. At the time I told a few friends, but wasn’t in a huge rush to find something else immediately; I’d been getting ready to depart for a little while, and there were some things (a bit of travel, catching up on some open-source projects, and ... Read full entry -
Efficient many-to-many field lookup in Django REST Framework
The basic setup Suppose you have these models: from django.db import models class Category(models.Model): name = models.CharField(max_length=100) class Blogpost(models.Model): title = models.CharField(max_length=100) categories = models.ManyToManyField(Category) Suppose you hook these up Django REST Framework and list all Blogpost items. Something like this: # urls.py from rest_framework import routers from . import views router = routers.DefaultRouter() router.register(r'blogposts', views.BlogpostViewSet) # views.py from rest_framework import viewsets class BlogpostViewSet(viewsets.ModelViewSet): queryset = Blogpost.objects.all().order_by('date') serializer_class = serializers.BlogpostSerializer What's the problem? Then, if you execute this list (e.g. curl http://localhost:8000/api/blogposts/) what will happen, on the database, is something like this: SELECT "app_blogpost"."id", "app_blogpost"."title" FROM "app_blogpost"; SELECT "app_category"."id", "app_category"."name" FROM "app_category" INNER JOIN "app_blogpost_categories" ON ("app_category"."id" = "app_blogpost_categories"."category_id") WHERE "app_blogpost_categories"."blogpost_id" = 1025; SELECT "app_category"."id", "app_category"."name" FROM "app_category" INNER JOIN "app_blogpost_categories" ON ("app_category"."id" = "app_blogpost_categories"."category_id") WHERE "app_blogpost_categories"."blogpost_id" = 193; SELECT "app_category"."id", "app_category"."name" FROM "app_category" INNER JOIN "app_blogpost_categories" ON ("app_category"."id" = "app_blogpost_categories"."category_id") WHERE "app_blogpost_categories"."blogpost_id" = 757; SELECT "app_category"."id", "app_category"."name" FROM "app_category" INNER JOIN "app_blogpost_categories" ON ("app_category"."id" = "app_blogpost_categories"."category_id") WHERE "app_blogpost_categories"."blogpost_id" = 853; SELECT "app_category"."id", "app_category"."name" FROM "app_category" INNER JOIN "app_blogpost_categories" ON ("app_category"."id" = "app_blogpost_categories"."category_id") WHERE "app_blogpost_categories"."blogpost_id" = 1116; SELECT "app_category"."id", "app_category"."name" FROM "app_category" INNER JOIN "app_blogpost_categories" ON ("app_category"."id" = "app_blogpost_categories"."category_id") WHERE "app_blogpost_categories"."blogpost_id" = 1126; SELECT "app_category"."id", "app_category"."name" FROM "app_category" INNER JOIN … -
Django, Sitemaps and alternates
Django, Sitemaps and alternates Django’s own sitemaps module is great for quickly generating sitemaps, but it unfortunately does not support more than the bare minimum of attributes. Also, it uses the template engine to create XML and this makes me sad. We had to add a sitemap.xml file to a customers’ website. The site supports several languages and runs on several domains, so we had to carefully specify alternate language pages and canonical URLs so that the website would be punished for duplicate content. Therefore, a year ago I set out to build a sitemaps app for Django which supports Django’s sitemaps, but also allows adding entries with additional attributes. The result of this work was django-sitemaps. from django_sitemaps import Sitemap def sitemap(request): sitemap = Sitemap(build_absolute_uri=request.build_absolute_uri) sitemap.add_django_sitemap(SomeSitemap, request=request) sitemap.add( url, changefreq='weekly', priority=0.5, lastmod=datetime.now(), alternates={ 'en': '...', 'en-ch': '...', 'en-gb': '...', 'de': '...', ... }, ) return sitemap.response(pretty_print=True) Today, I also added support for generating the most simple robots.txt files possible: All user agents, and only Sitemap: <absolute url> entries. The recommended usage is now (still using url() instead of path() because I’m old and rusty): from django_sitemaps import robots_txt from app.views import sitemap urlpatterns = [ url(r'^sitemap\.xml$', sitemap), url(r'^robots\.txt$', robots_txt(timeout=86400)), … -
Our approach to configuring Django, Webpack and ManifestStaticFilesStorage
Our approach to configuring Django, Webpack and ManifestStaticFilesStorage I spent some time finding out how Django and webpack should be configured so that they work well together both in development and in production. We are now using this setup on dozens of websites, so now is a good time to write down the approach. Requirements for development were: Hot module reloading (especially of CSS, but also of JavaScript code). Ability to use SCSS, ES6 and ES7. PostCSS support (although I currently only use the autoprefixer, nothing else). Requirements for production: Filenames depending on the content of assets, so that we can add far future expiry headers without worrying about cache busting, and not only for webpack-generated assets but also for everything else, so ManifestStaticFilesStorage is a must. Separate delivery of CSS and JavaScript code – we want to add CSS to the <head>, and JavaScript at the end of the <body>. Working webpack code splitting is a plus if possible. There are a few problems that have to be solved: Django has to know about asset URLs generated by webpack. Some assets are used both in HTML and in CSS/JavaScript code, e.g. a logo image. The obvious way to be … -
First Rotterdam (NL) Python meetup: my summaries
Welcome to the first Python Rotterdam meetup - Thijs Damsma He searched for python meetups in Rotterdam, but didn't find any. So he clicked on the "do you want to start one?" button. Today's meetup is at Van Oord (a big family owned marine contractor), but anywhere else in Rotterdam is fine. And you can help out. Everything is fine, from talks to workshops, as long as it is python-related. The goal is to have a few meetups per year. Jupyter lab - Joost Dobken Joost is a data engineer. He uses python daily, mostly jupyter notebooks. Jupyter notebooks are ideal for getting to know python, btw. Jupyter lab is the next iteration of notebooks. It is in beta, but usable. Normally, you still work in notebooks, but you can also start a regular python prompt or a terminal. It starts to look like an IDE: file browser, generic editor, etc. And very nice for data analysis, for instance with a fast CSV browser. He demoed the markdown integration. A source file with an (live updating) output window side by side. And a terminal window at the bottom. Very fancy: there is an extension that works with google docs. So … -
How to Record Video in OpenCV & Python
OpenCV makes it simple to reco... -
Open source activity (April 2018 edition)
It’s time for a post about recently released Django and Python packages by yours truly. Open source activity (April 2018 edition) django-imagefield A more opinionated version of django-versatileimagefield, which keeps the amount of code in production at a minumum has a strong preference towards generating images in advance, not on demand (which means it stays fast whatever the storage backend may be) fails early when invalid images are uploaded instead of crashing the website later speckenv speckenv helps keep configuration and secrets in the environment, not in the code. It knows how to parse .env files, and how to read structured values from the environment (not only strings, but also bools, lists, dictionaries – in short, Python literals) django-curtains It is useful to give clients protected access to a website in development. django-curtains allows keeping the work in progress secret by only allowing authenticated access (using either Django’s authentication system, or HTTP Basic authorization) Of course, activity on older projects hasn’t ceased either. New releases of xlsxdocument, django-user-messages, django-http-fallback-storage, html-sanitizer, feincms3, django-cabinet, django-authlib, etc. are available on PyPI. -
OpenCV & Python: How to Change Resolution or Rescale Frame
Let's assume you're working of... -
Reliable Way To Test External APIs Without Mocking
Let us write a function which retrieves user information from GitHub API. import requests def get_github_user_info(username): url = f'https://api.github.com/users/{username}' response = requests.get(url) if response.ok: return response.json() else: return None To test this function, we can write a test case to call the external API and check if it is returning valid data. def test_get_github_user_info(): username = 'ChillarAnand' info = get_github_user_info(username) assert info is not None assert username == info['login'] Even though this test case is reliable, this won't be efficient when we have many APIs to test as it sends unwanted requests to external API and makes tests slower due to I/O. A widely used solution to avoid external API calls is mocking. Instead of getting the response from external API, use a mock object which returns similar data. from unittest import mock def test_get_github_user_info_with_mock(): with mock.patch('requests.get') as mock_get: username = 'ChillarAnand' mock_get.return_value.ok = True json_response = {"login": username} mock_get.return_value.json.return_value = json_response info = get_github_user_info(username) assert info is not None assert username == info['login'] This solves above problems but creates additional problems. Unreliable. Even though test cases pass, we are not sure if API is up and is returning a valid response. Maintenance. We need to ensure mock responses are … -
Reliable Way To Test External APIs Without Mocking
Let us write a function which retrieves user information from GitHub API. import requests def get_github_user_info(username): url = f'https://api.github.com/users/{username}' response = requests.get(url) if response.ok: return response.json() else: return None To test this function, we can write a test case to call the external API and check if it is returning valid data. def test_get_github_user_info(): username = 'ChillarAnand' info = get_github_user_info(username) assert info is not None assert username == info['login'] Even though this test case is reliable, this won't be efficient when we have many APIs to test as it sends unwanted requests to external API and makes tests slower due to I/O. A widely used solution to avoid external API calls is mocking. Instead of getting the response from external API, use a mock object which returns similar data. from unittest import mock def test_get_github_user_info_with_mock(): with mock.patch('requests.get') as mock_get: username = 'ChillarAnand' mock_get.return_value.ok = True json_response = {"login": username} mock_get.return_value.json.return_value = json_response info = get_github_user_info(username) assert info is not None assert username == info['login'] This solves above problems but creates additional problems. Unreliable. Even though test cases pass, we are not sure if API is up and is returning a valid response. Maintenance. We need to ensure mock responses are … -
Resetting Django Migrations
Resetting Django Migrations Sometimes you’ll need to reset your Django migrations or simply make a clean up. This process can be performed very easily in many situations but can also become complex if you have a big number of migration files and database tables .In this tutorial I’ll show you a few options to enable you to effectively delete or reset your Django database migrations without affecting the working of your project. Case 1: Dropping the whole database is not a problem In this case we’ll describe how to rest database migrations in a situation where you don’t actually have a problem deleting or dropping your whole database. Deleting migration files Start by deleting each migration file inside your project apps except for the Python module file init.py You can use a bash script in Unix based operating systems to do this quickly: find . -path "*/migrations/*.py" -not -name "__init__.py" -delete find . -path "*/migrations/*.pyc" -delete The first line looks for Python files (migration files) inside migrations folder in each project’s app except for init.py then delete them. The second line looks for the Python compiled version of the previous migration files and delete them. Dropping the database The next … -
Adding dynamic dns hostnames to Django INTERNAL_IPS
While some of us are blessed with fixed IP addresses, some ISPs don’t offer this option unfortunately. If you’re using the Django INTERNAL_IPS setting to show or hide the debug toolbar this can be a problem. Luckily the Django settings files are pure Python and it’s easy enough to work around this issue with a few lines of code: import sys INTERNAL_IPS = [ # Any fixed internal IPs ] INTERNAL_HOSTS = [ # Some dyndns host # Some no-ip host # etc... # For example: 'wol.ph', ] # Only enable when running through the runserver command if 'runserver' in sys.path: import dns.resolver resolver = dns.resolver.Resolver() # Set the timeout to 1 so we don't wait too long resolver.timeout = 1 resolver.lifetime = 1 for host in INTERNAL_HOSTS: try: # For ipv6 you can use AAAA instead of A here ip = resolver.query(host, 'A')[0].address INTERNAL_IPS.append(ip) except dns.exception.Timeout: print('Unable to resolve %r, skipping' % host) Note that the code above uses dnspython which can be installed through pip. Link to this post!