Django community: RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
Simplifying your Django Frontend Tasks with Grunt
Grunt is a powerful task runner with an amazing assortment of plugins. It's not limited to the frontend, but there are many frontend-oriented plugins that you can take advantage of to combine and minify your static media, compile sass and less files, watch for changes during development and reload your browser automatically, and much more. In the last several years, the amount of tooling around frontend development has expanded dramatically. Frameworks, libraries, preprocessors and postprocessors, transpilers, template languages, module systems, and more! Wiring everything together has become a significant challenge, and a variety of build tools have emerged to help ease this burden. Grunt is the current leader because of its fantastic plugin community, and it contains a wide array of plugins that can be very valuable to a Django developer. Today I'm going to talk about an easy way to integrate Grunt with Django's runserver, and highlight a few plugins to handle common frontend tasks that Django developers often deal with. Installing Grunt Grunt uses Node.js, so you'll need to have that installed and configured on your system. This process will vary depending on your platform, but once it's done you'll need to install Grunt. From the documentation: $ … -
Simplifying your Django Frontend Tasks with Grunt
Grunt is a powerful task runner with an amazing assortment of plugins. It's not limited to the frontend, but there are many frontend-oriented plugins that you can take advantage of to combine and minify your static media, compile sass and less files, watch for changes during development and reload your browser automatically, and much more. In the last several years, the amount of tooling around frontend development has expanded dramatically. Frameworks, libraries, preprocessors and postprocessors, transpilers, template languages, module systems, and more! Wiring everything together has become a significant challenge, and a variety of build tools have emerged to help ease this burden. Grunt is the current leader because of its fantastic plugin community, and it contains a wide array of plugins that can be very valuable to a Django developer. Today I'm going to talk about an easy way to integrate Grunt with Django's runserver, and highlight a few plugins to handle common frontend tasks that Django developers often deal with. Installing Grunt Grunt uses Node.js, so you'll need to have that installed and configured on your system. This process will vary depending on your platform, but once it's done you'll need to install Grunt. From the documentation: $ … -
Looking forwards and backwards
We are almost a month into the new year, time to look forward.But first a look backwards. The year of 2013 was a year of big development projects and lots of quiet in the main repository in between. Two major updates were released during the year.The first update, the "many sessions per player" update, originated in a feature request that I thought would be easy to implement but which led to far-ranging changes (and honestly, improvements) to how Players and Sessions interconnect. It was a lot more more work than I anticipated.The second update was about moving Evennia's web server from the Portal level into the Server-level. The actual moving of the server was actually considerably easier than I thought it would be. But it turned out that a truckload of other things came along with it. Not only did the cache system have to change in order to accommodate the new webs erver, I had to also finalize the Out-of-band structure, since this made use of the cache system. And while I were at it, other fixes were done and ... the update grew and grew. When it finally merged late last year it closed plenty of issues, but it … -
Populate Your Test Database With Mixins
While Django has support for loading fixtures in its unit testing tools, I have found that maintaining fixtures over time is nothing less than a giant pain in the butt. As your model definitions change over time, remembering to re-run manage.py dumpdata myapp >fixtures.json any time your fixtures are affected is something I guarantee you will forget to do. Not to mention the fact that your database may or may not contain records suitable for testing at any given time. Then all of your unit tests have blown up, it takes you a little bit of time to figure out why, and before you know it you are cursing and out of your flow. For a time I tried using Alex Gaynor's django-fixture-generator but that only solved the problem of creating the records you want to test, not the problem of fixtures sitting on disk that are out of sync with your model schema. After being introduced to Django class-based views' mixin-heavy style, I cooked up a technique for unit test TestCase classes to create the records they need at runtime, thus bypassing the need for fixtures. In an apps tests/__init__.py I create a PopulateDbMixin: class PopulateDbMixin(object): def populate_db(self): """Assume … -
Populate Your Test Database With Mixins
While Django has support for loading fixtures in its unit testing tools, I have found that maintaining fixtures over time is nothing less than a giant pain in the butt. As your model definitions change over time, remembering to re-run manage.py dumpdata myapp >fixtures.json any time your fixtures are affected is something I guarantee you will forget to do. Not to mention the fact that your database may or may not contain records suitable for testing at any given time. Then all of your unit tests have blown up, it takes you a little bit of time to figure out why, and before you know it you are cursing and out of your flow. For a time I tried using Alex Gaynor's django-fixture-generator but that only solved the problem of creating the records you want to test, not the problem of fixtures sitting on disk that are out of sync with your model schema. After being introduced to Django class-based views' mixin-heavy style, I cooked up a technique for unit test TestCase classes to create the records they need at runtime, thus bypassing the need for fixtures. In an apps tests/__init__.py I create a PopulateDbMixin: class PopulateDbMixin(object): def populate_db(self): """Assume … -
Email Validation
Email validation has always been a bit of a nightmare. On the one hand there are all of the local domain names (sometimes even a single word can be a valid email) meanwhile there is an explosion of top level domain names confusing the entire internet for no reason I've been able to work out.Anyway my problem today is that my payment processor SagePay validates emails and will decline the transaction if the email validation fails. I am using Django's EmailField to validate the addresses but unfortunately SagePay and Django have different views on what is a valid email with SagePay being more strict.In a fit of optimism I emailed SagePay support to try to find out the algorithm, after a brief exchange of mails I got to it as "RFC532n" which completely mystified me (and Google!) However on reading their documentation I got referred to RFC3696 which made more sense although it is one of the RFC's which leaves things quite open with a lot of advice rather than firm rules. So I did a bit of testing to try to reverse engineer the SagePay algorithm and it looks like it is the Django algorithm with the addition of … -
Mercurial Mirror For Django 1.7 Branch
Today the Django project released the first alpha for Django 1.7. As such, the branch for 1.7 has been created in the git repository, and we can start mirroring it. Of course, this is still an alpha and the clone shouldn’t be used yet for prodution. The purpose is to test 1.7 early and to […] -
awesome-slugify: Human-readable URL slugs from any string (part 2)
In my previous blog post I covered using awesome-slugify to capture slugs in both ASCII and unicode. Today I'm covering the definition custom language slugify translation functions. Defining Custom Language slugify Translation Functions For those times we need ASCII representation of unicode characters, we can't always use the default unicode-to-ASCII mappings. A powerful feature of awesome-slugify is we can quickly and easily create our own translation functions. Just follow these two steps: Define a translation dictionary. Keys are the names of things you want translated, and the associated values are what the keys are translated into. Generate a translation function using slugify.main.get_slugify(). Explaining this in depth will take paragraphs of text, so I'll just demonstrate it using emoji: # -*- coding: utf-8 -*- # test_slugify_emoji.py from slugify import get_slugify import pytest # Step 1: Define the translation dictionary ALT_EMOJI = { u'ʘ‿ʘ': u'smiling', u'ಠ_ಠ': u'disapproval', u'♥‿♥': u'enamored', u'♥': u'love', } # Step 2: Generate a translation function slugify_emoji = get_slugify(pretranslate=ALT_EMOJI) def test_basic_emoji(): assert slugify_emoji(u"ʘ‿ʘ") == u"smiling" assert slugify_emoji(u"ಠ_ಠ") == u"disapproval" def test_sentence(): txt = u"I ♥ Audrey Roy Greenfeld" assert slugify_emoji(txt) == u"I-love-Audrey-Roy-Greenfeld" if __name__ == "__main__": pytest.main() More Practical Applications While writing an emoji-based translation function is fun, most … -
awesome-slugify: Human-readable URL slugs from any string (part 2)
In my previous blog post I covered using awesome-slugify to capture slugs in both ASCII and unicode. Today I'm covering the definition custom language slugify translation functions. Defining Custom Language slugify Translation Functions For those times we need ASCII representation of unicode characters, we can't always use the default unicode-to-ASCII mappings. A powerful feature of awesome-slugify is we can quickly and easily create our own translation functions. Just follow these two steps: Define a translation dictionary. Keys are the names of things you want translated, and the associated values are what the keys are translated into. Generate a translation function using slugify.main.get_slugify(). Explaining this in depth will take paragraphs of text, so I'll just demonstrate it using emoji: # -*- coding: utf-8 -*- # test_slugify_emoji.py # The way the awesome-slugify API works, you can't directly import from # the 'slugify' package. You have to import from the 'slugify.main' # module. See https://github.com/dimka665/awesome-slugify/issues/2 from slugify.main import get_slugify import pytest # Step 1: Define the translation dictionary ALT_EMOJI = { u'ʘ‿ʘ': u'smiling', u'ಠ_ಠ': u'disapproval', u'♥‿♥': u'enamored', u'♥': u'love', } # Step 2: Generate a translation function slugify_emoji = get_slugify(pretranslate=ALT_EMOJI) def test_basic_emoji(): # awesome-slugify capitalizes strings. # see https://github.com/dimka665/awesome-slugify/issues/3 assert slugify_emoji(u"ʘ‿ʘ") == u"Smiling" … -
awesome-slugify: Human-readable URL slugs from any string
note: The introduction mentions Django and Plone. However, this is not an article about Django or Plone. Introduction Years ago, when I was working with Plone at NASA, one thing I dreaded was when content editors would copy-and-paste from Microsoft Word into the title bar. All kinds of funny characters would appear in the title bar and URL. I would have to go into the database (ZODB) and fix things. Things didn't get better until Reed O'Brien turned on a title validator (probably in Plone.i18n). When we started using Django, one thing that made it nice was the presence of it's slugify() function and template filter. Inspired by the newspaper industry, this function it easier on both content editors and software engineers. In any case, using slugify() we completed a number of projects, with NASA Science being the only public one I worked on. As much as the slugify() function was useful, there were problems. As I discovered time and time again over the years, it didn't handle unicode. Or rather, it handled them by simply vanishing non-ASCII unicode characters. For example: >>> from django.utils.text import slugify >>> slugify(u"straße") # German for road u"strae" If you read German, you'll know … -
awesome-slugify: Human-readable URL slugs from any string
note: The introduction mentions Django and Plone. However, this is not an article about Django or Plone. Introduction Years ago, when I was working with Plone at NASA, one thing I dreaded was when content editors would copy-and-paste from Microsoft Word into the title bar. All kinds of funny characters would appear in the title bar and URL. I would have to go into the database (ZODB) and fix things. Things didn't get better until Reed O'Brien turned on a title validator (probably in Plone.i18n). When we started using Django, one thing that made it nice was the presence of it's slugify() function and template filter. Inspired by the newspaper industry, this function it easier on both content editors and software engineers. In any case, using slugify() we completed a number of projects, with NASA Science being the only public one I worked on. As much as the slugify() function was useful, there were problems. As I discovered time and time again over the years, it didn't handle unicode. Or rather, it handled them by simply vanishing non-ASCII unicode characters. For example: >>> from django.utils.text import slugify >>> slugify(u"straße") # German for road u"strae" If you read German, you'll know … -
Django Extensions 1.3.3
We are proud to release: Django-Extensions Version 1.3.3 This brings the usual tons of fixes and improvements Get it now: https://pypi.python.org/pypi/django-extensions/1.3.3 Changelog: Docs: Made it clearer that Django Extensions requires Django 1.4 or higher Translations: FR Updated Python3: Fix for shell_plus -
awesome-slugify: Human-readable URL slugs from any string
Years ago, when I was working with Plone at NASA, one thing I dreaded was when content editors would copy-and-paste from Microsoft Word into the title bar. All kinds of funny characters would appear in the title bar and URL. I would have to go into the database (ZODB) and fix things. Things didn't get better until Reed O'Brien turned on a title validator (probably in Plone.i18n). When we started using Django, one thing that made it nice was the presence of it's slugify() function and template filter. Inspired by the newspaper industry, this function it easier on both content editors and software engineers. In any case, using slugify() we completed a number of projects, with NASA Science being the only public one I worked on. As much as the slugify() function was useful, there were problems. As I discovered time and time again over the years, it didn't handle unicode. Or rather, it handled them by simply vanishing non-ASCII unicode characters. For example: >>> from django.utils.text import slugify >>> slugify(u"straße") # German for road u"strae" If you read German, you'll know that the default Django slugify() function is converting the word 'road' to nonsense. For sites dealing with internationalization, … -
ViewSets and Routers - django-rest-framework part 3
ViewSets and Routers are very useful for slimming up your code and providing a lot of default functionality out of the box. They are powerful features in django-rest-framework allowing a lot of flexibility in your code while keeping things clean.Watch Now... -
Django Best Practices -Django开发的最佳实践
推荐一篇Django的开发及部署的文章:Django Best Practices--A guide to d […] -
Just Married, and Proof #1 Is In
Happy 2014! We have a couple of exciting announcements: First, in case you haven't heard, Daniel and I just got married. It's not every day that co-authors of Django books get married, right? Here was our wedding cartwheel. Photo credit: Lindy DiMaio - Della Vita Photography. Second, the first print proof of Two Scoops of Django 1.6 arrived in the mail this week. Goodness, it is heavy! Here's how it compares to the 1.5 edition: Note that the final version may look drastically different -- right now we are tweaking colors and making lots of edits. In fact, it will still take several iterations before the book is ready. It may even take months. But hopefully not. Hopefully it'll be more like weeks. -
Just Married, and Proof #1 Is In
Happy 2014! We have a couple of exciting announcements: First, in case you haven't heard, Daniel and I just got married. It's not every day that co-authors of Django books get married, right? Here was our wedding cartwheel. Photo credit: Lindy DiMaio - Della Vita Photography. Second, the first print proof of Two Scoops of Django 1.6 arrived in the mail this week. Goodness, it is heavy! Here's how it compares to the 1.5 edition: Note that the final version may look drastically different -- right now we are tweaking colors and making lots of edits. In fact, it will still take several iterations before the book is ready. It may even take months. But hopefully not. Hopefully it'll be more like weeks. -
Just Married, and Proof #1 Is In
Happy 2014! We have a couple of exciting announcements: First, in case you haven't heard, Daniel and I just got married. It's not every day that co-authors of Django books get married, right? Here was our wedding cartwheel. Photo credit: Lindy DiMaio - Della Vita Photography. Second, the first print proof of Two Scoops of Django 1.6 arrived in the mail this week. Goodness, it is heavy! Here's how it compares to the 1.5 edition: Note that the final version may look drastically different -- right now we are tweaking colors and making lots of edits. In fact, it will still take several iterations before the book is ready. It may even take months. But hopefully not. Hopefully it'll be more like weeks. -
pytest: no-boilerplate testing (part 3)
-
pytest: no-boilerplate testing (part 3)
In my previous blog post I covered writing exception-based assertions and fixtures. Today I'm going to close things out by demonstrating how to change the behavior of pytest and how to integrate it with Django and setup.py. Changing the Behavior of pytest When pytest is called, either via the command-line or by pytest.main(), it looks for a configuration file called either pytest.ini, tox.ini, and setup.cfg. If it finds a configuration file, it follows standard practices for those things. In the following example, I demonstrating searching for tests inside of all Python files while ignoring the _build directories: # pytest.ini (or tox.ini or setup.cfg) [pytest] # You must put pytest-related controls in a 'pytest' block python_files=*.py # Run tests against all python modules norecursedirs = _build # Don't look inside of _build directories Changing pytest Behavior Dynamically This is pretty nice, but if I need to ignore certain Python modules like setup.py? I can do this by creating a conftest.py module and defining a collect_ignore variable. # conftest.py collect_ignore = ["setup.py", "conftest.py"] The conftest.py module can actually be defined per directory. So if test behavior needs to change in different packages, just create additional conftest.py modules. It's simple to do, but … -
pytest: no-boilerplate testing (part 2)
In my previous blog post I covered test discovery and writing basic tests using pytest. Today I'm going to cover a few more features that I really enjoy: raises and fixtures. The Intuitively Named raises context manager When using pytest, you can assert whether or not an exception occurred via the following: # test_exceptions.py from pytest import raises def test_an_exception(): with raises(IndexError): # Indexing the 30th item in a 3 item list [5, 10, 15][30] class CustomException(Exception): pass def test_my_exception(): with raises(CustomException): raise CustomException This is similar to, but just a bit easier to remember than the implementation in unittest. What I like about it is that even if I step away from code and tests for enough time to go on vacation and get married, when I come back I always remember the precise name of the context manager used to raise exceptions. Fixtures as Function Arguments When writing tests, it's not uncommon to need common objects used between tests. However, if you have a complicated process to generate these common objects, then you have to write tests for your tests. When using Python's venerable unittest framework, this always causes a spaghetti-code headache. However, via the virtue of simplicity, … -
pytest: no-boilerplate testing (part 2)
In my previous blog post I covered test discovery and writing basic tests using pytest. Today I'm going to cover a few more features that I really enjoy: raises and fixtures. The Intuitively Named raises context manager When using pytest, you can assert whether or not an exception occurred via the following: # test_exceptions.py from pytest import raises def test_an_exception(): with raises(IndexError): # Indexing the 30th item in a 3 item list [5, 10, 15][30] Fixtures as Function Arguments When writing tests, it's not uncommon to need common objects used between tests. However, if you have a complicated process to generate these common objects, then you have to write tests for your tests. When using Python's venerable unittest framework, this always causes a spaghetti-code headache. However, via the virtue of simplicity, pytest helps keep our test code cleaner and more maintainable. Rather than try and explain that further, I'll write some code to get my point across: # test_fixtures.py from pytest import fixture @fixture # Registering this function as a fixture. def complex_data(): # Creating test data entirely in this function to isolate it # from the rest of this module. class DataTypes(object): string = str list = list return … -
Sending emails with embedded images in Django
Django offers useful classes to easily send email. It is also easy to add attachments to emails. I did have to puzzle a bit to get embedded images working. This article describes the way I do it now. I will first describe the most important elements and then I will show a more complete example. The elements Since I send a plain text and HTML version of the email, I use the EmailMultiAlternatives class: msg = EmailMultiAlternatives(subject, text_content, sender, [to_mail]) The images are included as attachments. We do not use the attach_file method because we want to set the Content-ID header. This way we can refer to the image by that ID in the template. for f in ['logo.png', 'logo-footer.png']: fp = open(os.path.join(os.path.dirname(__file__), f), 'rb') msg_img = MIMEImage(fp.read()) fp.close() msg_img.add_header('Content-ID', '<{}>'.format(f)) msg.attach(msg_img) As far as I have seen, the images can only actually be included if the content type of the mail is correctly set. By default, the content type is set to “multipart/alternative”. But this resulted in the images just being displayed as attachments. What I needed was to set the content type to “multipart/related”: msg.mixed_subtype = 'related' (This is the thing that took the most time to figure … -
pytest: no-boilerplate testing
When I first encountered Holger Krekel's pytest this summer on Jeff Knupp's blog I felt like I had been living under a rock for years. I've been using Python's unittest framework since 2006 and nose to find tests since 2008, but here was another test framework dating back to at least January 24, 2007. pytest is a very mature testing tool for testing Python. My favorite features: It can run unittest, doctest, and nose, style tests suites, making it ideal for new and legacy projects. It includes an intuitively named raises context manager for testing exceptions. You can define fixture arguments to generate baseline data. This is very, very different from Django-style fixtures. Via pytest.ini you can change the behavior of pytest. Integrates nicely with setup.py. Alright, lets dive into usage. Test Discovery The first thing that pytest provides is test discovery. Like nose, starting from the directory where it is run, it will find any Python module prefixed with test_ and will attempt to run any defined unittest or function prefixed with test_. pytest explores properly defined Python packages, searching recursively through directories that include __init.py__ modules. Since an image is probably easier to read, here's a sample directory … -
pytest: no-boilerplate testing
When I first encountered Holger Krekel's pytest this summer on Jeff Knupp's blog I felt like I had been living under a rock for years. I've been using Python's unittest framework since 2006 and nose to find tests since 2008, but here was another test framework that actually predates nose! pytest is a very mature testing tool for testing Python. My favorite features: It can run unittest, doctest, and nose, style tests suites, making it ideal for new and legacy projects. It includes an intuitively named raises context manager for testing exceptions. You can define fixture arguments to generate baseline data. This is very, very different from Django-style fixtures. Via pytest.ini you can change the behavior of pytest. Integrates nicely with setup.py. Alright, lets dive into usage. Test Discovery The first thing that pytest provides is test discovery. Like nose, starting from the directory where it is run, it will find any Python module prefixed with test_ and will attempt to run any defined unittest or function prefixed with test_. pytest explores properly defined Python packages, searching recursively through directories that include __init__.py modules. Since an image is probably easier to read, here's a sample directory structure annotated with which …