<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>How-To on Caktus Group</title><link>https://www.caktusgroup.com/tags/how-to/</link><description>Recent content in How-To on Caktus Group</description><generator>Hugo</generator><language>en</language><lastBuildDate>Wed, 05 Apr 2023 14:00:00 +0000</lastBuildDate><atom:link href="https://www.caktusgroup.com/tags/how-to/index.xml" rel="self" type="application/rss+xml"/><item><title>Analyze data with SQL window functions</title><link>https://www.caktusgroup.com/blog/2023/04/05/analyze-data-sql-window-functions/</link><pubDate>Wed, 05 Apr 2023 14:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2023/04/05/analyze-data-sql-window-functions/</guid><description>&lt;p>We regularly use tools like &lt;a href="https://www.postgresql.org/" target="_blank" rel="noopener noreferrer">PostgreSQL&lt;/a>,
&lt;a href="https://pandas.pydata.org/" target="_blank" rel="noopener noreferrer">Pandas&lt;/a>, and &lt;a href="https://jupyter.org/" target="_blank" rel="noopener noreferrer">Jupyter
Notebooks&lt;/a> to analyze data here at Caktus.
Recently, we were reviewing North Carolina traffic stop data for the &lt;a href="https://nccopwatch.org/" target="_blank" rel="noopener noreferrer">NC
CopWatch&lt;/a> project and had the opportunity to
use &lt;a href="https://www.postgresql.org/docs/current/tutorial-window.html" target="_blank" rel="noopener noreferrer">PostgreSQL's window
functions&lt;/a>,
which are helpful when aggregating data.&lt;/p></description></item><item><title>How to Use Celery for Scheduling Tasks</title><link>https://www.caktusgroup.com/blog/2021/08/11/using-celery-scheduling-tasks/</link><pubDate>Wed, 11 Aug 2021 18:14:40 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2021/08/11/using-celery-scheduling-tasks/</guid><description>&lt;p>There are multiple ways to schedule tasks in your Django app, but there
are some advantages to using Celery. It&amp;rsquo;s supported, scales well, and
works nicely with Django. Given its wide use, there are also lots of
resources for learning more about it, and once learned, that knowledge
is likely to be useful on other projects.&lt;/p></description></item><item><title>How Mock Can Improve Your Unit Tests: Part 2</title><link>https://www.caktusgroup.com/blog/2021/04/05/mock-improve-unit-tests/</link><pubDate>Mon, 05 Apr 2021 12:54:21 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2021/04/05/mock-improve-unit-tests/</guid><description>&lt;p>In &lt;a href="https://www.caktusgroup.com/blog/2021/03/29/mock-unit-tests-part-1/">Part
1&lt;/a>
of this blog series, we started looking at how we can use mocking to
improve our unit tests. We'll expand on that in this post.&lt;/p></description></item><item><title>How Mock Can Improve Your Unit Tests: Part 1</title><link>https://www.caktusgroup.com/blog/2021/03/29/mock-unit-tests-part-1/</link><pubDate>Mon, 29 Mar 2021 12:54:20 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2021/03/29/mock-unit-tests-part-1/</guid><description>&lt;p>We've written in the past about the importance of unit tests and how to
write better ones: &lt;a href="https://www.caktusgroup.com/blog/2018/01/08/culture-unit-testing/">Culture of Unit
Testing&lt;/a>,
&lt;a href="https://www.caktusgroup.com/blog/2017/05/29/subtests-are-best/">Subtests are the
Best&lt;/a>.&lt;/p></description></item><item><title>Automating PyPI releases with Github Actions</title><link>https://www.caktusgroup.com/blog/2021/02/11/automating-pypi-releases/</link><pubDate>Thu, 11 Feb 2021 14:37:42 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2021/02/11/automating-pypi-releases/</guid><description>&lt;p>At Caktus, we maintain some &lt;a href="https://github.com/caktus" target="_blank" rel="noopener noreferrer">open source packages&lt;/a>, which are usually pieces of code that we&amp;rsquo;ve found useful when building an application, and we figure they might be useful to others. From time to time, those open source projects need a little maintenance: Maybe a bug fix has been provided from a community member, or we need to update to support a new version of Python or Django. I always hesitate to do this because I know there are multiple steps involved to ensure that any updates are properly tested, documented, versioned, and released. One of my silly blockers is that I always seem to forget how to upload a release to PyPI, which is the Python Package Index, a repository of software for Python. I call it silly because it shouldn’t really be a blocker, seeing how simple it actually is, but I still forget it each time and have to walk through the documentation step by step to make sure I do it properly. I recently found a tool that helps with this process.&lt;/p></description></item><item><title>JavaScript Variable Declaration in the 21st Century</title><link>https://www.caktusgroup.com/blog/2021/01/25/javascript-variable/</link><pubDate>Mon, 25 Jan 2021 15:32:15 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2021/01/25/javascript-variable/</guid><description>&lt;p>October 2020 marked the 14th anniversary of the introduction of &amp;ldquo;let&amp;rdquo;
and &amp;quot;const&amp;quot; to Javascript. Yes, it was in 2006 that this feature was
first introduced, and we&amp;rsquo;re still having conversations about it. So why,
you ask, are we still talking about this? It seems that a lot of
confusion remains, not to mention a lot of old code being passed around
on StackOverflow with &amp;ldquo;var&amp;rdquo; all over the place. Here I&amp;rsquo;ll discuss the
difference between these three declarations, and come to a conclusion
about best practices&lt;/p></description></item><item><title>My Python Development Environment</title><link>https://www.caktusgroup.com/blog/2021/01/14/python-development-environment/</link><pubDate>Thu, 14 Jan 2021 14:40:35 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2021/01/14/python-development-environment/</guid><description>&lt;p>This is how to set up the One True Development Environment for Python.&lt;/p>
&lt;p>Haha, just kidding, there is no such thing. Here's one way to do it
that works for me, and an attempt to explain the benefits of doing it
this way.&lt;/p></description></item><item><title>Our Top 20 Blogs in 2020</title><link>https://www.caktusgroup.com/blog/2021/01/05/top-20-blogs-2020/</link><pubDate>Tue, 05 Jan 2021 15:26:55 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2021/01/05/top-20-blogs-2020/</guid><description>&lt;p>We’ve published summaries of our most popular blog posts before (see &lt;a href="https://www.caktusgroup.com/blog/2020/01/01/top-19-blogs-2019/">Top 19 of 2019&lt;/a> and &lt;a href="https://www.caktusgroup.com/blog/2019/01/01/caktus-blog-top-18-posts-2018/">Top 18 of 2018&lt;/a>), but this time, we’re taking it a step further. We’re sharing the 20 most popular posts in 2020, regardless of the year the post was originally published. And some of these have been around a while! Based on total pageviews, here are the blogs that rose to the top of the popularity list, from most viewed to least viewed.&lt;/p></description></item><item><title>Build a useKeypress Hook in React</title><link>https://www.caktusgroup.com/blog/2020/07/01/usekeypress-hook-react/</link><pubDate>Wed, 01 Jul 2020 19:27:20 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2020/07/01/usekeypress-hook-react/</guid><description>&lt;p>One of the great patterns to come out of React 16.8 is composable hooks.
Using React's built-in hooks such as
&lt;a href="https://reactjs.org/docs/hooks-reference.html#usestate" target="_blank" rel="noopener noreferrer">useState&lt;/a> and
&lt;a href="https://reactjs.org/docs/hooks-reference.html#useeffect" target="_blank" rel="noopener noreferrer">useEffect&lt;/a>, we
can encapsulate and modularize bits of functionality &amp;mdash; almost the same
way we create reusable components. In this article we're going to throw
together a quick hook that registers an event listener on a keypress and
performs an action. Nothing fancy, but it's a nice abstraction that
makes it a lot easier to add some nice power-user features to your app.&lt;/p></description></item><item><title>How to Schedule Tasks Using Celery Beat in a Container</title><link>https://www.caktusgroup.com/blog/2020/05/14/how-schedule-tasks-using-celery-beat-container/</link><pubDate>Thu, 14 May 2020 12:30:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2020/05/14/how-schedule-tasks-using-celery-beat-container/</guid><description>&lt;p>When running services in a container, changes to files can be discarded
at any time, but the Celery beat default scheduler keeps its state in a
file.&lt;/p></description></item><item><title>How to Use Kubernetes on Azure for Cloud Computing</title><link>https://www.caktusgroup.com/blog/2020/04/28/how-use-kubernetes-azure-cloud-computing/</link><pubDate>Tue, 28 Apr 2020 18:41:03 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2020/04/28/how-use-kubernetes-azure-cloud-computing/</guid><description>&lt;p>For the &lt;a href="http://ratom.web.unc.edu/" target="_blank" rel="noopener noreferrer">Review, Appraisal, and Triage of Mail (RATOM)
project&lt;/a>, funded by the Andrew W. Mellon
Foundation, we were tasked with deploying to a Microsoft Azure
environment. More details about the project are in our &lt;a href="https://www.caktusgroup.com/blog/2020/03/19/email-extract-data-microsoft-pst-files/">first blog
post&lt;/a>
in this Learn With Us blog series. Caktus has experience with Amazon Web
Services (AWS) and Google Cloud, but we hadn't had the opportunity to
use Azure yet, so we looked forward to the opportunity to use that
environment and document our experience. The entire deployment process
is available on GitHub as a reference under the
&lt;a href="https://github.com/StateArchivesOfNorthCarolina/ratom-deploy" target="_blank" rel="noopener noreferrer">StateArchivesOfNorthCarolina/ratom-deploy&lt;/a>
repository.&lt;/p></description></item><item><title>What to do About Email: How to Extract Data from Microsoft PST Files</title><link>https://www.caktusgroup.com/blog/2020/03/19/email-extract-data-microsoft-pst-files/</link><pubDate>Thu, 19 Mar 2020 12:27:52 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2020/03/19/email-extract-data-microsoft-pst-files/</guid><description>&lt;p>In my previous line of work as an archivist, the question of what to do
about email archives was an ongoing and deeply-considered topic. Email
is everywhere. Yes, even Gen Z and millennials use it, despite thousands
of think pieces that would have you believe that the old ways are giving
way to business meetings conducted on fixed-gear bicycles, over avocado
toast and Instagram.&lt;/p></description></item><item><title>Creating a Sub-account in Amazon Web Services</title><link>https://www.caktusgroup.com/blog/2020/03/03/sub-account-amazon-web-services/</link><pubDate>Tue, 03 Mar 2020 20:20:50 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2020/03/03/sub-account-amazon-web-services/</guid><description>&lt;p>Anytime we host resources for a client within the Caktus Amazon Web
Services (AWS) account, we set up a sub-account and put the resources
there. Some of the advantages of doing this compared to putting a
client's resources in our main account are:&lt;/p></description></item><item><title>How to Use the "docker" Docker Image to Run Your Own Docker daemon</title><link>https://www.caktusgroup.com/blog/2020/02/25/docker-image/</link><pubDate>Tue, 25 Feb 2020 13:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2020/02/25/docker-image/</guid><description>&lt;p>There exists on Docker hub a Docker image called
&lt;a href="https://hub.docker.com/_/docker" target="_blank" rel="noopener noreferrer">docker&lt;/a>. It also has two flavors,
&amp;quot;stable&amp;quot; and a &amp;quot;dind&amp;quot; (Docker-in-Docker). What is this image for and
what is the purpose of these two different image tags?&lt;/p></description></item><item><title>Our Top 19 Blogs of 2019</title><link>https://www.caktusgroup.com/blog/2020/01/01/top-19-blogs-2019/</link><pubDate>Wed, 01 Jan 2020 17:17:32 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2020/01/01/top-19-blogs-2019/</guid><description>&lt;p>During the last year we gave our popular technical blog an official name: Developer Access. We published 32 posts on the blog, including technical how-to’s, conference information, web development best practices and detailed guides. Among all those posts, 19 rose to the top of the popularity list (based on total pageviews):&lt;/p></description></item><item><title>How to Do Wagtail Data Migrations</title><link>https://www.caktusgroup.com/blog/2019/09/12/wagtail-data-migrations/</link><pubDate>Thu, 12 Sep 2019 20:12:03 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2019/09/12/wagtail-data-migrations/</guid><description>&lt;p>&lt;a href="https://wagtail.io/" target="_blank" rel="noopener noreferrer">Wagtail&lt;/a> is a fantastic content management system
that does a great job of making it easy for developers to get a new
website up and running quickly and painlessly. It&amp;rsquo;s no wonder that
Wagtail has grown to become the leading Django-based CMS. &lt;a href="https://django-chat.simplecast.com/episodes/wagtail-cms-tom-dyson" target="_blank" rel="noopener noreferrer">As one of the
creators of Wagtail recently
said&lt;/a>,
it makes the initial experience of getting a website set up and running
very good. At Caktus, &lt;a href="https://www.caktusgroup.com/blog/2019/03/07/why-we-love-wagtail/">Wagtail is our go-to
framework&lt;/a>
when we need a content management system.&lt;/p></description></item><item><title>How to Import Multiple Excel Sheets in Pandas</title><link>https://www.caktusgroup.com/blog/2019/08/13/import-multiple-excel-sheets-pandas/</link><pubDate>Tue, 13 Aug 2019 12:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2019/08/13/import-multiple-excel-sheets-pandas/</guid><description>&lt;p>Pandas is a powerful Python data analysis tool. It's used heavily in
the data science community since its data structures make real-world
data analysis significantly easier. At Caktus, in addition to using it
for data exploration, we also incorporate it into Extract, Transform,
and Load (ETL) processes.&lt;/p></description></item><item><title>How to Set Up a Centralized Log Server with rsyslog</title><link>https://www.caktusgroup.com/blog/2019/06/20/how-to-set-up-centralized-log-server-rsyslog/</link><pubDate>Thu, 20 Jun 2019 12:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2019/06/20/how-to-set-up-centralized-log-server-rsyslog/</guid><description>&lt;p>For many years, we've been running an ELK (Elasticsearch, Logstash,
Kibana) stack for centralized logging. We have a specific project that
requires on-premise infrastructure, so sending logs off-site to a hosted
solution was not an option. Over time, however, the maintenance
requirements of this self-maintained ELK stack were staggering.
Filebeat, for example, filled up all the disks on all the servers in a
matter of hours, not once, but twice (and for different reasons) when it
could not reach its Logstash/Elasticsearch endpoint. Metricbeat suffered
from a similar issue: It used far too much disk space relative to the
value provided in its Elasticsearch indices. And while provisioning a
self-hosted ELK stack has gotten easier over the years, it's still a
lengthy process, which requires extra care anytime an upgrade is needed.
Are these problems solvable? Yes. But for our needs, a simpler solution
was needed.&lt;/p></description></item><item><title>How to Switch to a Custom Django User Model Mid-Project</title><link>https://www.caktusgroup.com/blog/2019/04/26/how-switch-custom-django-user-model-mid-project/</link><pubDate>Fri, 26 Apr 2019 16:32:33 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2019/04/26/how-switch-custom-django-user-model-mid-project/</guid><description>&lt;p>The Django documentation recommends always &lt;a href="https://docs.djangoproject.com/en/2.2/topics/auth/customizing/#using-a-custom-user-model-when-starting-a-project" target="_blank" rel="noopener noreferrer">starting your project with a
custom user
model&lt;/a>
(even if it's identical to Django's to begin with), to make it easier
to customize later if you need to. But what are you supposed to do if
you didn't see this when starting a project, or if you inherited a
project without a custom user model and you need to add one?&lt;/p></description></item><item><title>Coding for Time Zones &amp; Daylight Saving Time — Oh, the Horror</title><link>https://www.caktusgroup.com/blog/2019/03/21/coding-time-zones-and-daylight-saving-time/</link><pubDate>Thu, 21 Mar 2019 16:45:36 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2019/03/21/coding-time-zones-and-daylight-saving-time/</guid><description>&lt;p>In this post, I review some reasons why it's really difficult to
program correctly when using times, dates, time zones, and daylight
saving time, and then I'll give some advice for working with them in
Python and Django. Also, I'll go over why I hate daylight saving time
(DST).&lt;/p></description></item><item><title>Suggestions For Picking Up Old Projects</title><link>https://www.caktusgroup.com/blog/2019/02/15/old-projects/</link><pubDate>Fri, 15 Feb 2019 18:36:49 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2019/02/15/old-projects/</guid><description>&lt;p>At Caktus, we work on many projects, some of which are built by us from
start to finish, while others are inherited from other sources.
Oftentimes, we pick up a project that we either have not worked on in a
long time, or haven&amp;rsquo;t worked on at all, so we have to get familiar with
the code and figure out the design decisions that were made by those who
developed it (including when the developers are younger versions of
ourselves). Moreover, it is a good idea to improve the setup process in
each project, so others can have an easier time getting set up in the
future. In our efforts to work on such projects, a few things have been
helpful both for becoming familiar with the projects more quickly, and
for making the same projects easier to pick up in the future.&lt;/p></description></item><item><title>A Guide To Creating An API Endpoint With Django Rest Framework</title><link>https://www.caktusgroup.com/blog/2019/02/01/creating-api-endpoint-django-rest-framework/</link><pubDate>Fri, 01 Feb 2019 20:42:28 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2019/02/01/creating-api-endpoint-django-rest-framework/</guid><description>&lt;p>As part of our work to make sharp web apps at Caktus, we frequently
create API endpoints that allow other software to interact with a
server. Oftentimes this means using a frontend app (React, Vue, or
Angular), though it could also mean connecting some other piece of
software to interact with a server. A lot of our API endpoints, across
projects, end up functioning in similar ways, so we have become
efficient at writing them, and this blog post gives an example of how to
do so.&lt;/p></description></item><item><title>How to Use Django Bulk Inserts for Greater Efficiency</title><link>https://www.caktusgroup.com/blog/2019/01/09/django-bulk-inserts/</link><pubDate>Wed, 09 Jan 2019 13:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2019/01/09/django-bulk-inserts/</guid><description>&lt;p>It's been awhile since we &lt;a href="https://www.caktusgroup.com/blog/2011/09/20/bulk-inserts-django/">last discussed bulk
inserts&lt;/a>
on the Caktus blog. The idea is simple: if you have an application that
needs to insert a lot of data into a Django model &amp;mdash; for example a
background task that processes a CSV file (or some other text file) &amp;mdash;
it pays to &amp;quot;chunk&amp;quot; those updates to the database so that multiple
records are created through a single database operation. This reduces
the total number of round-trips to the database, something my colleague
Dan Poirier discussed in more detail in the post linked above.&lt;/p></description></item><item><title>Caktus Blog: Top 18 Posts of 2018</title><link>https://www.caktusgroup.com/blog/2019/01/01/caktus-blog-top-18-posts-2018/</link><pubDate>Tue, 01 Jan 2019 13:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2019/01/01/caktus-blog-top-18-posts-2018/</guid><description>&lt;p>In 2018, we published 44 posts on our blog, including technical how-to’s, a series on UX research methods, web development best practices, and tips for project management. Among all those posts, 18 rose to the top of the popularity list in 2018.&lt;/p></description></item><item><title>How to Fix your Python Code's Style</title><link>https://www.caktusgroup.com/blog/2018/12/10/how-to-fix-python-code-style/</link><pubDate>Mon, 10 Dec 2018 12:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2018/12/10/how-to-fix-python-code-style/</guid><description>&lt;p>Sometimes we inherit code that doesn't follow the style guidelines we
prefer when we're writing new code. We could just run
&lt;a href="http://flake8.pycqa.org/en/latest/" target="_blank" rel="noopener noreferrer">flake8&lt;/a> on the whole codebase and
fix everything before we continue, but that's not necessarily the best
use of our time.&lt;/p></description></item><item><title>Filtering and Pagination with Django</title><link>https://www.caktusgroup.com/blog/2018/10/18/filtering-and-pagination-django/</link><pubDate>Thu, 18 Oct 2018 14:40:42 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2018/10/18/filtering-and-pagination-django/</guid><description>&lt;p>If you want to build a list page that allows filtering and pagination,
you have to get a few separate things to work together. Django provides
some tools for pagination, but the documentation doesn't tell us how to
make that work with anything else. Similarly, django_filter makes it
relatively easy to add filters to a view, but doesn't tell you how to
add pagination (or other things) without breaking the filtering.&lt;/p></description></item><item><title>Better Python Dependency Management with pip-tools</title><link>https://www.caktusgroup.com/blog/2018/09/18/python-dependency-management-pip-tools/</link><pubDate>Tue, 18 Sep 2018 14:37:29 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2018/09/18/python-dependency-management-pip-tools/</guid><description>&lt;p>I recently looked into whether I could use
&lt;a href="https://github.com/jazzband/pip-tools" target="_blank" rel="noopener noreferrer">pip-tools&lt;/a> to improve my
workflow around projects' Python dependencies. My conclusion was that
pip-tools would help on some projects, but it wouldn't do everything I
wanted, and I couldn't use it everywhere. (I tried pip-tools version
2.0.2 in August 2018. If there are newer versions, they might fix some
of the things I ran into when trying pip-tools.)&lt;/p></description></item><item><title>Make ALL Your Django Forms Better</title><link>https://www.caktusgroup.com/blog/2018/06/18/make-all-your-django-forms-better/</link><pubDate>Mon, 18 Jun 2018 13:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2018/06/18/make-all-your-django-forms-better/</guid><description>&lt;p>Website experiences need to be consistent as much as they need to be well thought out and aesthetically pleasing. Structure, visual design, user interactions, and accessibility concerns are among many considerations that go into building quality websites. While achieving consistency of experience and implementation is an essential goal of web development, efficiency of execution is also very important. An efficient workflow means this consistent experience doesn’t require redoing work across the site.&lt;/p></description></item><item><title>Creating Dynamic Forms with Django</title><link>https://www.caktusgroup.com/blog/2018/05/07/creating-dynamic-forms-django/</link><pubDate>Mon, 07 May 2018 13:30:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2018/05/07/creating-dynamic-forms-django/</guid><description>&lt;p>&lt;em>Editor&amp;rsquo;s note: This post was written in 2018 when Django 1.11 and Django 2.0 were current. The code samples may need to be updated to work with more recent versions of Django.&lt;/em>&lt;/p></description></item><item><title>Supercharging your CSS with Stylus and PostCSS</title><link>https://www.caktusgroup.com/blog/2017/12/18/supercharging-your-css-stylus-and-postcss/</link><pubDate>Mon, 18 Dec 2017 14:30:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2017/12/18/supercharging-your-css-stylus-and-postcss/</guid><description>&lt;p>Here at Caktus the front-end team stays on the bleeding edge by taking
advantage of the latest and greatest tools. We only incorporate features
into our packaging that are well-supported and production-ready, as well
as those that meet our list of standard browser requirements. Luckily,
there are plenty of tools that allow us to use experimental technologies
with appropriate fallbacks for non-supported browsers.&lt;/p></description></item><item><title>Building a Custom Block Template Tag</title><link>https://www.caktusgroup.com/blog/2017/05/01/building-custom-block-template-tag/</link><pubDate>Mon, 01 May 2017 13:30:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2017/05/01/building-custom-block-template-tag/</guid><description>&lt;p>Building custom tags for Django templates has gotten much easier over
the years, with decorators provided that do most of the work when
building common, simple kinds of tags.&lt;/p></description></item><item><title>Learning to ask the right questions, or people</title><link>https://www.caktusgroup.com/blog/2017/04/10/learning-ask-right-questions-or-people/</link><pubDate>Mon, 10 Apr 2017 13:30:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2017/04/10/learning-ask-right-questions-or-people/</guid><description>&lt;p>I ask a lot of questions as a developer. Some of them have been more basic, like ‘How do I import a Python function from one file into another?’, and some more complex, like ‘How should we take an API request and return a dynamically-generated PDF as a response?’&lt;/p></description></item><item><title>How to write a bug report</title><link>https://www.caktusgroup.com/blog/2017/02/15/how-to-write-a-bug-report/</link><pubDate>Wed, 15 Feb 2017 13:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2017/02/15/how-to-write-a-bug-report/</guid><description>&lt;p>Here are some brief thoughts on writing good bug reports in general.&lt;/p>
&lt;h2 id="main-elements">Main elements&lt;/h2>
&lt;p>There are four crucial elements when writing a bug report:&lt;/p></description></item><item><title>New white paper: "Shipping faster: Django team improvements"</title><link>https://www.caktusgroup.com/blog/2016/04/04/new-white-paper-shipping-faster-django-team-improvements/</link><pubDate>Mon, 04 Apr 2016 13:26:38 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2016/04/04/new-white-paper-shipping-faster-django-team-improvements/</guid><description>&lt;p>For the past couple months, we’ve been working on a new white paper, “&lt;a href="http://learn.caktusgroup.com/shipping-faster-django-team-improvements?utm_source=web&amp;amp;utm_medium=bloglaunch&amp;amp;utm_campaign=shippingfaster" target="_blank" rel="noopener noreferrer">Shipping Faster: Django Team Improvements&lt;/a>”. We examined our existing processes, looked at best practices, and considered what has or hasn’t worked across our dozens of simultaneous projects.&lt;/p></description></item><item><title>AWS load balancers with Django</title><link>https://www.caktusgroup.com/blog/2015/08/10/aws-load-balancers-django/</link><pubDate>Mon, 10 Aug 2015 12:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2015/08/10/aws-load-balancers-django/</guid><description>&lt;p>We recently had occasion to reconfigure some of our existing servers to use Amazon Web Services Elastic Load Balancers in front of them. Setting this up isn&amp;rsquo;t hard, exactly, but there are a lot of moving parts that have to mesh correctly before things start to work, so I thought I&amp;rsquo;d write down what we did.&lt;/p></description></item><item><title>Django Logging Configuration: How the Default Settings Interfere with Yours</title><link>https://www.caktusgroup.com/blog/2015/01/27/Django-Logging-Configuration-logging_config-default-settings-logger/</link><pubDate>Tue, 27 Jan 2015 16:04:04 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2015/01/27/Django-Logging-Configuration-logging_config-default-settings-logger/</guid><description>&lt;p>My colleague &lt;a href="http://www.caktusgroup.com/about/vinod-kurup/" target="_blank" rel="noopener noreferrer">Vinod&lt;/a> recently found the answer on Stack Overflow to something that&amp;rsquo;s been bugging me for a long time - why do my Django logging configurations so often not do what I think they should?&lt;/p></description></item><item><title>Webinar: Testing Client-Side Applications with Django</title><link>https://www.caktusgroup.com/blog/2015/01/20/webinar-testing-client-side-applications-django/</link><pubDate>Tue, 20 Jan 2015 16:40:09 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2015/01/20/webinar-testing-client-side-applications-django/</guid><description>&lt;p>Technical Director &lt;a href="http://www.caktusgroup.com/about/mark-lavin/" target="_blank" rel="noopener noreferrer">Mark Lavin&lt;/a> will be hosting a free &lt;a href="http://www.oreilly.com/pub/e/3302" target="_blank" rel="noopener noreferrer">O’Reilly webinar&lt;/a> today at 4PM EST or 1PM PT on Testing Client-Side Applications with Django. Mark says testing is one of the most popular question topics he receives. It’s also a topic near and dear to Caktus’ quality-loving heart. Mark’s last webinar garnered more than 500 viewers, so sign up quick!&lt;/p></description></item><item><title>Using Amazon S3 to Store your Django Site's Static and Media Files</title><link>https://www.caktusgroup.com/blog/2014/11/10/Using-Amazon-S3-to-store-your-Django-sites-static-and-media-files/</link><pubDate>Mon, 10 Nov 2014 16:28:11 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2014/11/10/Using-Amazon-S3-to-store-your-Django-sites-static-and-media-files/</guid><description>&lt;p>&lt;em>Editor's note: This post was updated in September 2017.&lt;/em>&lt;/p>
&lt;h2 id="using-amazon-s3-to-store-your-django-sites-static-and-media-files">Using Amazon S3 to Store your Django Site's Static and Media Files&lt;/h2>
&lt;p>Storing your Django site's static and media files on Amazon S3, instead
of serving them yourself, can improve site performance. It frees your
servers from handling static files themselves, lets you scale your
servers easier by keeping media files in a common place, and is a
necessary step to using Amazon CloudFront as a Content Delivery Network
(CDN).&lt;/p></description></item><item><title>Webcast: Creating Enriching Web Applications with Django and Backbone.js</title><link>https://www.caktusgroup.com/blog/2014/11/04/enriching-web-apps-django-backbonejs/</link><pubDate>Tue, 04 Nov 2014 15:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2014/11/04/enriching-web-apps-django-backbonejs/</guid><description>&lt;p>&lt;strong>Update: The live webcast is now available at &lt;a href="http://www.oreilly.com/pub/e/3154" target="_blank" rel="noopener noreferrer">O&amp;rsquo;Reilly Media&lt;/a>&lt;/strong>&lt;/p>
&lt;p>Our technical director, Mark Lavin, will be giving a tutorial on Django and Backbone.js during a free webcast for O’Reilly Media tomorrow, November 6th, 1pm EST. There will be demos and a discussion of common stumbling blocks when building rich client apps.&lt;/p></description></item><item><title>Celery in Production</title><link>https://www.caktusgroup.com/blog/2014/09/29/celery-production/</link><pubDate>Mon, 29 Sep 2014 12:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2014/09/29/celery-production/</guid><description>&lt;p>(Thanks to &lt;a href="https://www.caktusgroup.com/about/mark-lavin/">Mark Lavin&lt;/a> for significant
contributions to this post.)&lt;/p>
&lt;p>In a &lt;a href="https://www.caktusgroup.com/blog/2014/06/23/scheduling-tasks-celery/">previous post&lt;/a>, we
introduced using Celery to schedule tasks.&lt;/p>
&lt;p>In this post, we address things you might need to consider when planning
how to deploy Celery in production.&lt;/p></description></item><item><title>Getting Started Scheduling Tasks with Celery</title><link>https://www.caktusgroup.com/blog/2014/06/23/scheduling-tasks-celery/</link><pubDate>Mon, 23 Jun 2014 11:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2014/06/23/scheduling-tasks-celery/</guid><description>&lt;p>&lt;strong>UPDATE:&lt;/strong> &lt;a href="https://www.caktusgroup.com/blog/2021/08/11/using-celery-scheduling-tasks/">A newer version of this blog post is available for Celery
Version
5.0.x&lt;/a>.&lt;/p>
&lt;h2 id="getting-started-using-celery-for-scheduling-tasks">Getting Started Using Celery for Scheduling Tasks&lt;/h2>
&lt;p>Many Django applications can make good use of being able to schedule
work, either periodically or just not blocking the request thread.&lt;/p></description></item><item><title>Managing Events with Explicit Time Zones</title><link>https://www.caktusgroup.com/blog/2014/01/09/managing-events-explicit-time-zones/</link><pubDate>Thu, 09 Jan 2014 14:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2014/01/09/managing-events-explicit-time-zones/</guid><description>&lt;h2 id="managing-events-with-explicit-time-zones">Managing Events with Explicit Time Zones&lt;/h2>
&lt;p>Recently we wanted a way to let users create real-life events which
could occur in any time zone that the user desired. By default, Django
interprets any date/time that the user enters as being in the user&amp;rsquo;s
time zone, but it never displays that time zone, and it converts the
time zone to UTC before storing it, so there is no record of what time
zone the user initially chose. This is fine for most purposes, but if
you want to specifically give the user the ability to choose different
time zones for different events, this won&amp;rsquo;t work.&lt;/p></description></item><item><title>Using strace to Debug Stuck Celery Tasks</title><link>https://www.caktusgroup.com/blog/2013/10/30/using-strace-debug-stuck-celery-tasks/</link><pubDate>Wed, 30 Oct 2013 19:56:31 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2013/10/30/using-strace-debug-stuck-celery-tasks/</guid><description>&lt;p>&lt;a href="http://www.celeryproject.org/" target="_blank" rel="noopener noreferrer">Celery&lt;/a> is a great tool for background
task processing in &lt;a href="https://www.djangoproject.com/" target="_blank" rel="noopener noreferrer">Django&lt;/a>. We use it
in a lot of the custom web apps we build at Caktus, and it's quickly
becoming the standard for all variety of task scheduling work loads,
from simple to highly complex.&lt;/p></description></item><item><title>Skipping Test DB Creation</title><link>https://www.caktusgroup.com/blog/2013/10/02/skipping-test-db-creation/</link><pubDate>Wed, 02 Oct 2013 12:48:59 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2013/10/02/skipping-test-db-creation/</guid><description>&lt;p>We are always looking for ways to make our tests run faster. That means
writing tests which don't preform I/O (DB reads/writes, disk
reads/writes) when possible. Django has a &lt;a href="https://docs.djangoproject.com/en/stable/topics/testing/overview/#provided-test-case-classes" target="_blank" rel="noopener noreferrer">collection of TestCase
subclasses&lt;/a>
for different use cases. The common &lt;code>TestCase&lt;/code> handles the fixture
loading and the creation the of &lt;code>TestClient&lt;/code>. It uses the database
transactions to ensure that the database state is reset for every test.
That is it wraps each test in a transaction and rolls it back once the
test is over. Any transaction management inside the test becomes a
no-op. Since [TestCase]{.title-ref}[ overrides the transaction
facilities, if you need to test the transactional behavior of a piece of
code you can instead use
]{.title-ref}[TransactionTestCase]{.title-ref}[.
]{.title-ref}[TransactionTestCase]{.title-ref}` resets the database
after the test runs by truncating all tables which is much slower than
rolling back the transaction particularly if you have a large number of
tables.&lt;/p></description></item><item><title>Central logging in Django with Graylog2 and graypy</title><link>https://www.caktusgroup.com/blog/2013/09/18/central-logging-django-graylog2-and-graypy/</link><pubDate>Wed, 18 Sep 2013 14:00:12 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2013/09/18/central-logging-django-graylog2-and-graypy/</guid><description>&lt;p>Django's &lt;a href="https://docs.djangoproject.com/en/1.5/topics/logging/" target="_blank" rel="noopener noreferrer">logging
configuration&lt;/a>
facilities, which arrived in version 1.3, have greatly eased (and
standardized) the process of configuring logging for Django projects.
When building complex and interactive web applications at Caktus, we've
found that detailed (and properly configured!) logs are key to
successful and efficient debugging. Another step in that process &amp;mdash;
which can be particularly useful in environments where you have multiple
web servers &amp;mdash; is setting up a centralized logging server to receive
all your logs and make them available through an easily accessible web
interface. There are a number useful tools to do this, but one we've
found that works quite well is &lt;a href="http://graylog2.org/" target="_blank" rel="noopener noreferrer">Graylog2&lt;/a>.
Installing and configuring Graylog2 is outside the scope of this post,
but there are plenty of tutorials on how to do so accessible through
your search engine of choice.&lt;/p></description></item><item><title>Migrating to a Custom User Model in Django</title><link>https://www.caktusgroup.com/blog/2013/08/07/migrating-custom-user-model-django/</link><pubDate>Wed, 07 Aug 2013 13:10:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2013/08/07/migrating-custom-user-model-django/</guid><description>&lt;p>&lt;strong>UPDATE: Read a&lt;/strong> &lt;a href="https://www.caktusgroup.com/blog/2019/04/26/how-switch-custom-django-user-model-mid-project/">&lt;strong>newer blog post on this
topic&lt;/strong>&lt;/a>.&lt;/p>
&lt;p>The new &lt;a href="https://docs.djangoproject.com/en/1.5/topics/auth/customizing/" target="_blank" rel="noopener noreferrer">custom user model
configuration&lt;/a>
that arrived in Django makes it relatively straightforward to swap in
your own model for the Django user model. In most cases, Django's
built-in &lt;code>User&lt;/code> model works just fine, but there are times when certain
limitations (such as the &lt;a href="https://docs.djangoproject.com/en/1.5/ref/models/fields/#emailfield" target="_blank" rel="noopener noreferrer">length of the email
field&lt;/a>)
require a custom user model to be installed. If you're starting out
with a custom user model, setup and configuration are relatively
straightforward, but if you need to migrate an existing legacy project
(e.g., one that started out in Django 1.4 or earlier), there are a few
gotchas that you might run into. We did this recently for one of our
larger, long-term client projects at Caktus, and here's an outline of
how we'd recommend tackling this issue:&lt;/p></description></item><item><title>MEDIA_ROOT and Django Tests</title><link>https://www.caktusgroup.com/blog/2013/06/26/media-root-and-django-tests/</link><pubDate>Wed, 26 Jun 2013 14:54:30 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2013/06/26/media-root-and-django-tests/</guid><description>&lt;p>If you&amp;rsquo;ve ever written a test for a view or model with associated
uploaded files you might have noticed a small problem with those files
hanging around after the tests are complete. Since version 1.3, Django
won&amp;rsquo;t delete the files associated with your model instances when they
are deleted. &lt;a href="http://stackoverflow.com/questions/5372934/how-do-i-get-django-admin-to-delete-files-when-i-remove-an-object-from-the-datab" target="_blank" rel="noopener noreferrer">Some work-arounds for this
issue&lt;/a>
involve writing a custom delete for your model or using a post_delete
signal handler. But even with those in place the files would not be
deleted during tests because the model instances are not explicitly
deleted at the end of the test case. Instead, Django simply rolls back
the transaction and the delete method is never called nor are the
signals fired. This can be quite an annoyance when running the tests
repeatedly and watching your &lt;code>MEDIA_ROOT&lt;/code> (or worse your S3 bucket) fill
up with garbage data. More than annoyance, this introduces something you
always want to avoid in unittests: global state.&lt;/p></description></item><item><title>Making your Django app more pluggable</title><link>https://www.caktusgroup.com/blog/2013/06/12/making-your-django-app-more-pluggable/</link><pubDate>Wed, 12 Jun 2013 12:08:27 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2013/06/12/making-your-django-app-more-pluggable/</guid><description>&lt;p>This blog post is about ways of doing things in your Django app, and
pitfalls to avoid, so your app is easier to plug in to other sites.&lt;/p></description></item><item><title>Managing Django Translations with Transifex</title><link>https://www.caktusgroup.com/blog/2013/04/25/managing-django-translations-transifex/</link><pubDate>Thu, 25 Apr 2013 15:51:27 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2013/04/25/managing-django-translations-transifex/</guid><description>&lt;p>We manage a number of open source Django apps here at Caktus. While many
of us here are proficient in a number of programming languages, the same
can&amp;rsquo;t be said for our ability to read or write in languages other than
English. The Django community is global and we want our apps to support
other languages. For that we&amp;rsquo;ve turned
to &lt;a href="https://www.transifex.com/" target="_blank" rel="noopener noreferrer">Transifex&lt;/a> which it the same tool Django
itself uses for translations.&lt;/p></description></item><item><title>A helper script for runserver</title><link>https://www.caktusgroup.com/blog/2013/04/11/helper-script-runserver/</link><pubDate>Thu, 11 Apr 2013 16:17:37 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2013/04/11/helper-script-runserver/</guid><description>&lt;h4 id="my-django-runserver-shortcut-script">My Django runserver shortcut script&lt;/h4>
&lt;p>This is a little shell script I save as &lt;code>rs&lt;/code>, put on my path, and use as
a shortcut to start the Django development server. It has several
features that make me more productive:&lt;/p></description></item><item><title>Using LESS with Django</title><link>https://www.caktusgroup.com/blog/2012/03/05/using-less-django/</link><pubDate>Mon, 05 Mar 2012 14:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2012/03/05/using-less-django/</guid><description>&lt;p>Lately, I&amp;rsquo;ve been working on creating a simplified work flow for my front end work here at Caktus. There are all sorts of new and helpful tools to optimize the creative process, allowing for faster iterations, and greater overall enjoyment. As with any new tool, there are a few options to choose from: LESS and SASS. Having read lots of reviews and reading through the documentation, I&amp;rsquo;ve decided LESS is more for me.&lt;/p></description></item><item><title>Configuring a Jenkins Slave</title><link>https://www.caktusgroup.com/blog/2012/01/10/configuring-jenkins-slave/</link><pubDate>Tue, 10 Jan 2012 13:50:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2012/01/10/configuring-jenkins-slave/</guid><description>&lt;p>We're pretty avid testers here at Caktus and when one of our Django
projects required upgrading to Python 2.7, we also needed to upgrade our
Jenkins build environment. Luckily, Jenkins supports distributed builds
to allow a master install to delegate tasks to slaves instances. This
way we can continue to run our primary build system on Ubuntu 10.04,
which defaults to Python 2.6, and delegate tasks to an Ubuntu 11.04
environment running Python 2.7. The setup is fairly easy, but since I
didn't find much out there already, I figured I write up a quick post
outlining what we did.&lt;/p></description></item><item><title>Class-based views in Django 1.3</title><link>https://www.caktusgroup.com/blog/2011/12/29/class-based-views-django-13/</link><pubDate>Thu, 29 Dec 2011 11:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2011/12/29/class-based-views-django-13/</guid><description>&lt;p>Django class-based views&lt;/p>
&lt;hr>
&lt;h3 id="introduction">Introduction&lt;/h3>
&lt;p>Django 1.3 added class-based views, but neglected to provide
documentation to explain what they were or how to use them. So here's a
basic introduction.&lt;/p></description></item><item><title>OpenBlock Geocoder, Part 3: External Geocoders</title><link>https://www.caktusgroup.com/blog/2011/12/28/openblock-geocoder-part-3-external-geocoders/</link><pubDate>Wed, 28 Dec 2011 13:23:21 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2011/12/28/openblock-geocoder-part-3-external-geocoders/</guid><description>&lt;p>The OpenBlock geocoder is powerful and robust. It uses PostGIS for
spacial queries, can extract addresses from bodies of text, and can
understand block and intersection notation. We've run into a few issues
with it, however, including a low geocoding success rate. This is a
tough problem to solve and depends on a lot of factors (the extent of
street and block data in OpenBlock, format of the street addresses,
etc.), so your mileage may vary. Below I constructed a simple test using
Google's Geocoding API to have as an alternative.&lt;/p></description></item><item><title>Using Django and Celery with Amazon SQS</title><link>https://www.caktusgroup.com/blog/2011/12/19/using-django-and-celery-amazon-sqs/</link><pubDate>Mon, 19 Dec 2011 16:26:48 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2011/12/19/using-django-and-celery-amazon-sqs/</guid><description>&lt;p>Amazon's &lt;a href="http://aws.amazon.com/sqs/" target="_blank" rel="noopener noreferrer">Simple Queue Service&lt;/a> (SQS) is a
relatively new offering in the family of Amazon Web Services (AWS).
It's also an appealing one, because it proposes to quickly and easily
replace a common component of the stack in a typical web application,
thereby obviating the need to run a separate queue server like
&lt;a href="http://www.rabbitmq.com/" target="_blank" rel="noopener noreferrer">RabbitMQ&lt;/a>. While RabbitMQ &amp;mdash; the typical
favorite for Celery users &amp;mdash; is not necessarily difficult to install or
maintain, removing it from the stack of a web application means one less
component that might fail, offloading that service to AWS &amp;mdash; especially
for applications with a small to moderate queue volume &amp;mdash; might prove
financially advantageous.&lt;/p></description></item><item><title>OpenBlock Geocoder, Part 2: Text Parsing and Entity Extraction</title><link>https://www.caktusgroup.com/blog/2011/12/16/openblock-geocoder-part-2-text-parsing-and-entity-extraction/</link><pubDate>Fri, 16 Dec 2011 13:30:19 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2011/12/16/openblock-geocoder-part-2-text-parsing-and-entity-extraction/</guid><description>&lt;p>This is the second post in our &lt;a href="https://github.com/openrural" target="_blank" rel="noopener noreferrer">OpenRural&lt;/a>
series reviewing &lt;a href="http://openblockproject.org/" target="_blank" rel="noopener noreferrer">OpenBlock&lt;/a> and it's
geocoder. &lt;a href="http://www.caktusgroup.com/blog/2011/12/12/openblock-geocoder-part-1-data-model-and-geocoding/" target="_blank" rel="noopener noreferrer">OpenBlock Geocoder, Part 1: Data Model and
Geocoding&lt;/a>
covers the internals of the OpenBlock geocoder and it's geocoding
capabilities. As this posts builds upon topics covered there, you may
wish to read Part 1 before proceeding. In this post we step back from
the internals of the geocoder and explore how to use it along with other
OpenBlock tools to parse unstructured text.&lt;/p></description></item><item><title>OpenBlock Geocoder, Part 1: Data Model and Geocoding</title><link>https://www.caktusgroup.com/blog/2011/12/12/openblock-geocoder-part-1-data-model-and-geocoding/</link><pubDate>Mon, 12 Dec 2011 16:17:20 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2011/12/12/openblock-geocoder-part-1-data-model-and-geocoding/</guid><description>&lt;p>As Tobias mentioned in &lt;a href="http://www.caktusgroup.com/blog/2011/12/06/scraping-data-and-web-standards/">Scraping Data and Web Standards&lt;/a>, Caktus is collaborating with the UNC School of Journalism to help develop Open Rural (the code is on &lt;a href="https://github.com/openrural">GitHub&lt;/a>). Open Rural hopes to help rural newspapers in North Carolina leverage &lt;a href="http://openblockproject.org/">OpenBlock&lt;/a>. This blog post is the first of several covering the internals of OpenBlock and, specifically, the geocoder.&lt;/p></description></item><item><title>Django Without the Web</title><link>https://www.caktusgroup.com/blog/2011/10/24/django-without-web/</link><pubDate>Mon, 24 Oct 2011 16:00:00 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2011/10/24/django-without-web/</guid><description>&lt;p>One of the things I like best about Django is how easy its ORM makes it
to work with databases. Too bad Django is only for web applications.
Sure, you could deploy a Django app and then make use of it from a
non-web application using a REST API, but that would be too awkward.&lt;/p></description></item><item><title>Bulk inserts in Django</title><link>https://www.caktusgroup.com/blog/2011/09/20/bulk-inserts-django/</link><pubDate>Tue, 20 Sep 2011 18:08:52 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2011/09/20/bulk-inserts-django/</guid><description>&lt;p>I recently found a way to speed up a large data import far more than I
expected.&lt;/p>
&lt;p>The task was to read data from a text file and create data records in
Django, and the naive implementation was managing to import about 55
records per second, which was going to take far too long given the
amount of data that needed to be imported.&lt;/p></description></item><item><title>Testing Web Server Configurations with Fabric and ApacheBench</title><link>https://www.caktusgroup.com/blog/2011/09/13/testing-web-server-configurations-fabric-and-apachebench/</link><pubDate>Tue, 13 Sep 2011 18:16:33 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2011/09/13/testing-web-server-configurations-fabric-and-apachebench/</guid><description>&lt;p>Load testing a site with ApacheBench is fairly straight forward.
Typically you'd just SSH to a machine on the same network as the one
you want to test, and run a command like this:&lt;/p></description></item><item><title>Getting Started using Python in Eclipse</title><link>https://www.caktusgroup.com/blog/2011/08/31/getting-started-using-python-eclipse/</link><pubDate>Wed, 31 Aug 2011 19:05:53 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2011/08/31/getting-started-using-python-eclipse/</guid><description>&lt;p>Eclipse with the PyDev module has a lot to offer the Python programmer
these days. If you haven't looked at PyDev before, or not in a while,
it's worth checking out.&lt;/p></description></item><item><title>Simplifying the Testing of Unmanaged Database Models in Django (Updated for Django 4.2 in 2024)</title><link>https://www.caktusgroup.com/blog/2010/09/24/simplifying-the-testing-of-unmanaged-database-models-in-django/</link><pubDate>Fri, 24 Sep 2010 15:01:09 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2010/09/24/simplifying-the-testing-of-unmanaged-database-models-in-django/</guid><description>&lt;p>&lt;em>Editor's note: This post was originally published in September, 2010
and was updated in December, 2024 to incorporate changes in Django and
improvements suggested by our readers. It has also been tested for
compatibility as of the Django 4.2 release.&lt;/em>&lt;/p></description></item><item><title>Basic Django deployment with virtualenv, fabric, pip and rsync</title><link>https://www.caktusgroup.com/blog/2010/04/22/basic-django-deployment-with-virtualenv-fabric-pip-and-rsync/</link><pubDate>Fri, 23 Apr 2010 00:46:37 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2010/04/22/basic-django-deployment-with-virtualenv-fabric-pip-and-rsync/</guid><description>&lt;p>Deployment is usually a tedious process with lots of tinkering until
everything is setup just right. We deploy quite a few Django sites on a
regular basis here at Caktus and still do tinkering, but we've
attempted to functionalize some of the core tasks to ease the process.
I've put together a basic example that outlines local and remote
environment setup. This is a simplified example and just one of many
ways to deploy a Django project (I learned a lot from Jacob
Kaplan-Moss'
&lt;a href="http://github.com/jacobian/django-deployment-workshop/" target="_blank" rel="noopener noreferrer">django-deployment-workshop&lt;/a>),
so I encourage you to browse around the Django community to learn more.
The entire source for this example project can be found in the
&lt;a href="http://www.bitbucket.org/copelco/caktus-deployment/src/tip/example-django-project/" target="_blank" rel="noopener noreferrer">caktus-deployment Bitbucket
repository&lt;/a>.&lt;/p></description></item><item><title>Decoupled Django Apps and the Beauty of Generic Relations</title><link>https://www.caktusgroup.com/blog/2010/03/11/decoupled-django-apps-and-the-beauty-of-generic-relations/</link><pubDate>Thu, 11 Mar 2010 21:18:02 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2010/03/11/decoupled-django-apps-and-the-beauty-of-generic-relations/</guid><description>&lt;p>Like just about everyone else, we've written our own suite of tools to
help with building complex content management systems in Django here at
&lt;a href="https://www.caktusgroup.com/services">Caktus&lt;/a>. We reviewed a number of the existing CMSes out
there, but in almost every case the navigation and page structure were
so tightly coupled the system broke down when it came time to add
additional, non-CMS pages.&lt;/p></description></item><item><title>Continuous Integration with Django and Hudson CI (Day 1)</title><link>https://www.caktusgroup.com/blog/2010/03/08/django-and-hudson-ci-day-1/</link><pubDate>Mon, 08 Mar 2010 15:58:48 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2010/03/08/django-and-hudson-ci-day-1/</guid><description>&lt;p>We're always looking for new tools to make our development environment
more robust here at Caktus. We write a lot of
&lt;a href="https://www.caktusgroup.com/blog/2009/05/26/testing-django-views-for-concurrency-issues/">tests&lt;/a>
to ensure proper functionality as new features land and bug fixes are
added to our projects. The next step is to integrate with a &lt;a href="http://en.wikipedia.org/wiki/Continuous_integration" target="_blank" rel="noopener noreferrer">continuous
integration&lt;/a> system
to automate the process and regularly check that status of the build.&lt;/p></description></item><item><title>Custom JOINs with Django's query.join()</title><link>https://www.caktusgroup.com/blog/2009/09/28/custom-joins-with-djangos-queryjoin/</link><pubDate>Mon, 28 Sep 2009 14:26:02 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/09/28/custom-joins-with-djangos-queryjoin/</guid><description>&lt;p>Django's ORM is great. It handles simple to fairly complex queries
right out the box without having to write any SQL. If you need a
complicated query, Django's lets you use .extra(), and you can always
fallback to raw SQL if need be, but then you lose the ORM's bells and
whistles. So it's always nice to find solutions that allow you to tap
into the ORM at different levels.&lt;/p></description></item><item><title>Creating recursive, symmetrical many-to-many relationships in Django</title><link>https://www.caktusgroup.com/blog/2009/08/14/creating-recursive-symmetrical-many-to-many-relationships-in-django/</link><pubDate>Fri, 14 Aug 2009 18:10:43 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/08/14/creating-recursive-symmetrical-many-to-many-relationships-in-django/</guid><description>&lt;p>In Django, a recursive many-to-many relationship is a &lt;code>ManyToManyField&lt;/code>
that points to the same model in which it's defined &lt;code>('self')&lt;/code>. A
symmetrical relationship is one in where, when &lt;code>a.contacts = [b]&lt;/code>, a is
in &lt;code>b.contacts&lt;/code>.&lt;/p></description></item><item><title>Setting PostgreSQL's SHMMAX in Mac OS X 10.5 (Leopard)</title><link>https://www.caktusgroup.com/blog/2009/08/13/setting-postgresqls-shmmax-in-mac-os-x-105-leopard/</link><pubDate>Thu, 13 Aug 2009 11:46:08 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/08/13/setting-postgresqls-shmmax-in-mac-os-x-105-leopard/</guid><description>&lt;p>If you've ever tried to increase the
&lt;a href="http://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-SHARED-BUFFERS" target="_blank" rel="noopener noreferrer">shared_buffers&lt;/a>
setting in your postgresql.conf to a value that exceeds the amount of
shared memory supported by your operating system kernel, then you'll
see an error message like this:&lt;/p></description></item><item><title>Towards a Standard for Django Session Messages</title><link>https://www.caktusgroup.com/blog/2009/06/19/towards-a-standard-for-django-session-messages/</link><pubDate>Fri, 19 Jun 2009 15:31:13 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/06/19/towards-a-standard-for-django-session-messages/</guid><description>&lt;p>Django needs a standard way in which session-specific messages can be created and retrieved for display to the user. For years we&amp;rsquo;ve been surviving using &lt;code>user.message_set&lt;/code> to store messages that are really specific to the current session, not the user, or using the latest and greatest Django snippet, pluggable app, or custom crafted middleware to handle messages in a more appropriate way.&lt;/p></description></item><item><title>Remote logging with Python logging and Django</title><link>https://www.caktusgroup.com/blog/2009/06/09/remote-logging-with-python-logging-and-django/</link><pubDate>Tue, 09 Jun 2009 12:47:10 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/06/09/remote-logging-with-python-logging-and-django/</guid><description>&lt;p>As part of my work on &lt;a href="http://www.everywatt.com/" target="_blank" rel="noopener noreferrer">EveryWatt&lt;/a>, our
fledgling energy monitoring web site, I needed a way to consolidate log
messages from all the data loggers we have running in a single place. If
you're not familiar with it, Python's &lt;a href="http://docs.python.org/library/logging.html" target="_blank" rel="noopener noreferrer">logging
module&lt;/a> is good stuff and
worth checking out. We already used it for logging to files locally, and
the module defines an
&lt;a href="http://docs.python.org/library/logging.html#logging.handlers.HTTPHandler" target="_blank" rel="noopener noreferrer">HTTPHandler&lt;/a>
that can deliver log messages to a remote server via HTTP.&lt;/p></description></item><item><title>Testing Django Views for Concurrency Issues (Updated for Django 4.2 in 2024)</title><link>https://www.caktusgroup.com/blog/2009/05/26/testing-django-views-for-concurrency-issues/</link><pubDate>Tue, 26 May 2009 19:59:25 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/05/26/testing-django-views-for-concurrency-issues/</guid><description>&lt;p>&lt;em>Editor's note: This post was originally published in May, 2009 and was
updated in December, 2024 to incorporate changes in Django and
improvements suggested by our readers. It has also been tested for
compatibility as of the Django 4.2 release.&lt;/em>&lt;/p></description></item><item><title>Explicit Table Locking with PostgreSQL and Django</title><link>https://www.caktusgroup.com/blog/2009/05/26/explicit-table-locking-with-postgresql-and-django/</link><pubDate>Tue, 26 May 2009 18:59:10 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/05/26/explicit-table-locking-with-postgresql-and-django/</guid><description>&lt;p>By default, &lt;a href="http://www.djangoproject.com/" target="_blank" rel="noopener noreferrer">Django&lt;/a> doesn't do explicit
table locking. This is OK for most read-heavy scenarios, but sometimes
you need guaranteed, exclusive access to the data. Caktus uses
&lt;a href="http://www.postgresql.org/" target="_blank" rel="noopener noreferrer">PostgreSQL&lt;/a> in most of our production
environments, so we can use the &lt;a href="http://www.postgresql.org/docs/8.3/interactive/explicit-locking.html" target="_blank" rel="noopener noreferrer">various lock
modes&lt;/a>
it provides to control concurrent access to the data. Once we obtain a
lock in PostgreSQL, it is held for the remainder of the current
transaction. Django provides transaction management, so all we need to
do is execute a &lt;a href="http://www.postgresql.org/docs/8.3/interactive/sql-lock.html" target="_blank" rel="noopener noreferrer">SQL LOCK
statement&lt;/a>
within a transaction, and Django and PostgreSQL will handle the rest.&lt;/p></description></item><item><title>Parsing Microseconds in a Django Form</title><link>https://www.caktusgroup.com/blog/2009/05/26/parsing-microseconds-in-a-django-form/</link><pubDate>Tue, 26 May 2009 13:43:56 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/05/26/parsing-microseconds-in-a-django-form/</guid><description>&lt;p>There's currently no way to accept microsecond-precision input through
a Django form's DateTimeField. This is an &lt;a href="http://code.djangoproject.com/ticket/9459%20" target="_blank" rel="noopener noreferrer">acknowledged
bug&lt;/a>, but the official
solution might not come very soon, because the real fix is non-trivial.&lt;/p></description></item><item><title>Seamlessly switch off (and on) a Django (or other WSGI) site for upgrades</title><link>https://www.caktusgroup.com/blog/2009/05/25/seamlessly-switch-off-and-on-a-django-or-other-wsgi-site-for-upgrades/</link><pubDate>Mon, 25 May 2009 19:53:18 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/05/25/seamlessly-switch-off-and-on-a-django-or-other-wsgi-site-for-upgrades/</guid><description>&lt;p>In preparation for migrating the &lt;a href="http://www.everywatt.com" target="_blank" rel="noopener noreferrer">EveryWatt&lt;/a>
database from one machine to another, I wrote this little
&lt;a href="http://www.wsgi.org/wsgi/What_is_WSGI" target="_blank" rel="noopener noreferrer">WSGI&lt;/a> script to easily disable
the site while I copy the data. Since it doesn't depend on
&lt;a href="http://www.djangoproject.com/" target="_blank" rel="noopener noreferrer">Django&lt;/a> or really anything else (other
than a functioning WSGI server), you can use it for other upgrades, too.&lt;/p></description></item><item><title>Eclipse Ganymede and Subclipse on Ubuntu - JavaHL (JNI) not available</title><link>https://www.caktusgroup.com/blog/2009/05/21/eclipse-ganymede-and-subsclipe-on-ubuntu-javahl-jni-not-available/</link><pubDate>Thu, 21 May 2009 15:10:25 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/05/21/eclipse-ganymede-and-subsclipe-on-ubuntu-javahl-jni-not-available/</guid><description>&lt;p>I finally got around to updating my &lt;a href="http://www.eclipse.org" target="_blank" rel="noopener noreferrer">Eclipse&lt;/a>,
&lt;a href="http://pydev.sourceforge.net/" target="_blank" rel="noopener noreferrer">PyDev&lt;/a>, and
&lt;a href="http://subclipse.tigris.org/" target="_blank" rel="noopener noreferrer">Subclipse&lt;/a> environment today, which I use
for &lt;a href="http://www.djangoproject.com" target="_blank" rel="noopener noreferrer">Django&lt;/a> development.&lt;/p>
&lt;p>Formerly I was using the SvnKit (pure-Java) libraries. SvnKit &amp;quot;felt&amp;quot;
slow to me, compared to my command line SVN client, so this time I tried
to get the JavaHL (JNI) libraries working.&lt;/p></description></item><item><title>Downsizing an LVM/RAID root partition</title><link>https://www.caktusgroup.com/blog/2009/04/23/recovering-lvm-on-raid/</link><pubDate>Thu, 23 Apr 2009 20:04:03 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/04/23/recovering-lvm-on-raid/</guid><description>&lt;p>At Caktus we use
&lt;a href="http://en.wikipedia.org/wiki/Logical_Volume_Manager_%28Linux%29" target="_blank" rel="noopener noreferrer">LVM2&lt;/a> on a
&lt;a href="http://en.wikipedia.org/wiki/RAID_1#RAID_1" target="_blank" rel="noopener noreferrer">RAID1&lt;/a> device to ease disk
management on a number of our servers. Recently I needed to downsize the
root partition of one of the servers, so I rebooted onto an Ubuntu 8.10
LiveCD and attempted to load the RAID/LVM info.&lt;/p></description></item><item><title>Migrating from django-photologue 1.x to 2.x</title><link>https://www.caktusgroup.com/blog/2009/03/27/migrating-from-django-photologue-1x-to-2x/</link><pubDate>Fri, 27 Mar 2009 17:52:30 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/03/27/migrating-from-django-photologue-1x-to-2x/</guid><description>&lt;p>We're in the process of updating a web app for a client that was built
last year about this time using &lt;a href="http://www.djangoproject.com" target="_blank" rel="noopener noreferrer">Django&lt;/a>
and &lt;a href="http://code.google.com/p/django-photologue/" target="_blank" rel="noopener noreferrer">Photologue&lt;/a>. Needless
to say, there have been a lot of changes to both over the past year!&lt;/p></description></item><item><title>Solving NFS issues on embedded machines</title><link>https://www.caktusgroup.com/blog/2009/03/25/solving-nfs-issues-on-embedded-machines/</link><pubDate>Wed, 25 Mar 2009 16:07:27 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/03/25/solving-nfs-issues-on-embedded-machines/</guid><description>&lt;p>As part of my work on &lt;a href="http://www.everywatt.com" target="_blank" rel="noopener noreferrer">EveryWatt&lt;/a>, I setup an
NFS-based development environment for one of the data loggers we use for
energy monitoring in the Caktus office. The stock 2.4 Linux kernel in
the machine seemed to have some trouble mounting the file system root I
had exported from one of our servers. The symptoms included long delays
for most if not all activities that used the file system and lots of
messages like these in dmesg:&lt;/p></description></item><item><title>Overriding Django admin templates for fun and profit</title><link>https://www.caktusgroup.com/blog/2009/01/20/overriding-django-admin-templates-for-fun-and-profit/</link><pubDate>Tue, 20 Jan 2009 18:25:48 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2009/01/20/overriding-django-admin-templates-for-fun-and-profit/</guid><description>&lt;h4 id="motivation--goal">Motivation &amp;amp; Goal&lt;/h4>
&lt;p>I sometimes find the admin interface's lists of instances of models
overwhelming. The filters and searching helps, but it would be nice to
get an overview of the data that is being shown. Particularly I wanted
to generate a graph based on the filters selected by the user, so that
only items displayed after a filter would be graphed.&lt;/p></description></item><item><title>Entering Contacts in CiviCRM</title><link>https://www.caktusgroup.com/blog/2008/11/05/entering-contacts-in-civicrm/</link><pubDate>Wed, 05 Nov 2008 20:29:51 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2008/11/05/entering-contacts-in-civicrm/</guid><description>&lt;p>One of our non-profit clients recently asked for help entering the
numerous business cards they get at trade shows, etc., into their
Customer Relationship Management database, a copy of
&lt;a href="http://www.civicrm.org" target="_blank" rel="noopener noreferrer">CiviCRM&lt;/a> that &lt;a href="http://www.caktusgroup.com/services/non-profit/" target="_blank" rel="noopener noreferrer">we setup and manage for
them&lt;/a>. The best path
for entering contacts isn't necessarily obvious from the get-go, but
the following procedure is the best we've found and has the lowest
up-front investment (you might be able to do something more efficient
with a Profile, but that doesn't seem as flexible with respect to
matching existing contacts).&lt;/p></description></item><item><title>Is Asterisk More Silent Than You'd Like?</title><link>https://www.caktusgroup.com/blog/2007/12/15/is-asterisk-more-silent-than-youd-like/</link><pubDate>Sat, 15 Dec 2007 19:06:01 +0000</pubDate><guid>https://www.caktusgroup.com/blog/2007/12/15/is-asterisk-more-silent-than-youd-like/</guid><description>&lt;p>At Caktus, we use the &lt;a href="http://www.asterisk.org/" target="_blank" rel="noopener noreferrer">Asterisk&lt;/a> open source
telephony platform. While setting up Asterisk, we tested a number of
different system environments and configurations to help determine what
would best fit our telephone needs. This involved running Asterisk on
both real and virtual machines and testing several configuration front
ends, including &lt;a href="http://www.freepbx.org/" target="_blank" rel="noopener noreferrer">FreePBX&lt;/a> and
&lt;a href="http://destar.berlios.de/" target="_blank" rel="noopener noreferrer">DeStar&lt;/a>. This article discusses a fairly
technical problem we confronted while installing a basic Asterisk setup
on the Debian GNU/Linux operating system (on real hardware); namely,
when the ztdummy Linux kernel module was loaded, Asterisk was unable to
play back any recordings (even its own). When we unloaded the ztdummy
module, however, recordings would play back fine. The catch, of course,
was that we needed ztdummy loaded for conference room support.&lt;/p></description></item></channel></rss>