Django community: Community blog posts RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
Attaching custom exceptions to functions and classes
Having too many custom exceptions on a project can be a pain, but a few choices ones are really nice. The problem is that in complex libraries having to import both functions and exceptions becomes a drag. To mitigate having to remember to import custom exceptions, this is a handy pattern you can use in a project and can be done on both functions and classes. Attaching a custom exception to a function This works because Python functions are first-class objects. They can be passed around as things, and in this case, have things assigned to them. # logic.py class DoesNotCompute(Exception): """ Easy to understand naming conventions work best! """ pass def this_function(x): """ This function only works on numbers.""" try: return x ** x except TypeError: raise DoesNotCompute # Assign DoesNotCompute exception to this_function this_function.DoesNotCompute = DoesNotCompute Now I can import the function, and it won't just through DoesNotCompute exceptions, it will also carry the function along with the import: >>> from logic import this_function >>> this_function(5) 3125 >>> this_function(4.5) 869.8739233809259 >>> this_function('will throw an error.') Traceback (most recent call last): File "<input>", line 1, in <module> File "logic.py", line 10, in this_function raise DoesNotCompute DoesNotCompute Alright, that doesn't … -
Attaching custom exceptions to functions and classes
Having too many custom exceptions on a project can be a pain, but a few choices ones are really nice. The problem is that in complex libraries having to import both functions and exceptions becomes a drag. To mitigate having to remember to import custom exceptions, this is a handy pattern you can use in a project and can be done on both functions and classes. Attaching a custom exception to a function This works because Python functions are first-class objects. They can be passed around as things, and in this case, have things assigned to them. # logic.py class DoesNotCompute(Exception): """ Easy to understand naming conventions work best! """ pass def this_function(x): """ This function only works on numbers.""" try: return x ** x except TypeError: raise DoesNotCompute # Assign DoesNotCompute exception to this_function this_function.DoesNotCompute = DoesNotCompute Now I can import the function, and it won't just through DoesNotCompute exceptions, it will also carry the function along with the import: >>> from logic import this_function >>> this_function(5) 3125 >>> this_function(4.5) 869.8739233809259 >>> this_function('will throw an error.') Traceback (most recent call last): File "<input>", line 1, in <module> File "logic.py", line 10, in this_function raise DoesNotCompute DoesNotCompute Alright, that doesn't … -
South 0.7.6 released
As the post title implies, yet another version of the ever-popular migrations library is out. The major addition in this release is --update, courtesy of Michael Elsdörfer - it lets you update an existing migration in-place for minor changes when you haven't committed the migration yet. There's also quite a few other changes - see the release notes for more. -
Attaching custom exceptions to functions and classes
Having too many custom exceptions on a project can be a pain, but a few choices ones are really nice. The problem is that in complex libraries having to import both functions and exceptions becomes a drag. To mitigate having to remember to import custom exceptions, this is a handy pattern you can use in a project and can be done on both functions and classes. Attaching a custom exception to a function This works because Python functions are first-class objects. They can be passed around as things, and in this case, have things assigned to them. # logic.py class DoesNotCompute(Exception): """ Easy to understand naming conventions work best! """ pass def this_function(x): """ This function only works on numbers.""" try: return x ** x except TypeError: raise DoesNotCompute # Assign DoesNotCompute exception to this_function this_function.DoesNotCompute = DoesNotCompute Now I can import the function, and it won't just through DoesNotCompute exceptions, it will also carry the function along with the import: >>> from logic import this_function >>> this_function(5) 3125 >>> this_function(4.5) 869.8739233809259 >>> this_function('will throw an error.') Traceback (most recent call last): File "<input>", line 1, in <module> File "logic.py", line 10, in this_function raise DoesNotCompute DoesNotCompute Alright, that doesn't … -
Announcing Django Dash 2012
Announcing Django Dash 2012 -
The road to hell is paved with regular expressions …
… or what is the cost of using regular expressions for simple tasks Regular expressions are one of the most powerful tools in computing I have ever seen. My previous post about Django compressor and image preloading is a good example how useful they might be. The only limit of their use is your imagination. But “with great power, comes great responsibility” or in this case a great cost. Even the simplest expressions can be quite heavy compared with other methods. The reason to write about this is a question recently asked in a python group. It was about how to get the elements of a list that match specific string. My proposal was to use comprehension list and simple string comparison while other member proposed using a regular expression. I was pretty sure that the regular expression is slower but not sure exactly how much slower so I made a simple test to find out. import re import timeit my_list = ['abc-123', 'def-456', 'ghi-789', 'abc456', 'abc', 'abd'] def re_check(): return [i for i in my_list if re.match('^abc$', i)] t = timeit.Timer(re_check) print 're_check result >>', re_check() print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000) def simple_check(): return [i for i … -
Filtres a l'admin de Django 1.4
En una de les darreres aplicacions que hem fet, la d'apibaleares hem tirat força de l'administrador de Django. Segurament i donades les característiques que volem que tengui l'apliació al final, anirem cap a un administrador ad-hoc, però ara per començar va força bé. Un dels primers problemes va sorgir amb els filtres. Amb l'admin de Django és molt senzill fer un filtre per qualsevol camp, però té l'emperò que si el camp és una clau forana cap a una altra taula amb molts elements Django et pinta tots els elements, amb la qual cosa la plana creix molt i el llista es fa mal de manejar. Amb Django 1.4 tenim l'opció de crear-nos els nostres propis filtres i dir-li a l'admin que els faci servir. Per posar-vos en situació el que voldríem és que enlloc del filtre com a llista per la clau forana, poguéssim seleccionar l'element a filtrar des d'un desplegable. És veritat que perdem la selecció múltiple, però a l'usuari no li fa res, el que no vol és tota la llista al costat dret del llistat. Així doncs, el primer que farem serà veure què hi ha respecte als filtres. La documentació de Django es minsa, potser … -
RapidSMS UNICEF Rwanda Conference
Recently, I have had the pleasure of attending the UNICEF Rwanda conference with Tobias. The conference is focused on developing a comprehensive eHealth suite for numerous nations to implement. Mobile technology is changing the landscape of public health, and SMS messaging is leading the way. Conference goers were tasked with organizing the existing eHealth and mHealth technical infrastructure to reduce redundancy in the existing applications. The goal was to create a comprehensive eHealth/mHealth software suite for maternal, newborn and child health, nutrition and Ending Mother to Child transmission of HIV (eMTCT). The conference also hoped to improve the interoperability of key existing platforms to provide functionality that is currently not possible by using one software tool. Caktus was very excited to take part in this conference and learn more about how developers can assist with the creation of useful health tools. Recently, Colin Copeland and I have become RapidSMS community coordinators. Our goals are to strengthen the existing infrastructure and write documentation for the existing code so that the application. The main goal for the RapidSMS project is to be fully usable by UNICEF country offices and other users without sustained support from outside software consultants. Through attending the UNICEF … -
Breakage when upgrading from Celery 2.5.3 -> 3.0.4
Commenting on my update to my Celery rant, @asksol asked me to post the Pylint results that made me question the claim of backwards compatibility. (“@Asksol asked” — See what I did there? That’s alliteration. It’s a sign of a quality blog post. Ask for it by name.) Again for the record, @asksol is a smart and friendly person. I know I wouldn’t last a day supporting a project the way he has supported Celery over multiple years. I’ve calmed down since yesterday, and I hope that something good results from my rant — if not for me, then for a future Celery user needing upgrade help. In his reply to my rant, @asksol describes some history and rationale for how he manages code change, and I encourage you to read it. Here we go: With django-celery 2.5.5, celery 2.5.3, Pylint 0.25.1, and a pylint.cfg that disables “W0511,R0904,R0801,R0903,C0302,R0922,R0914,R0902,C0111,R0912,R0915,I0011,W0232″, Pylint reports nothing. When I upgrade to django-celery 3.0.4 and celery 3.0.4, Pylint reports: $ fab pylint [localhost] local: pylint --rcfile="/Users/johnd/Documents/dev-quisitor/dev/configs/pylint.cfg" ips_quisitor ************* Module ips_quisitor.accounts.tasks E0611: 2,0: No name 'PeriodicTask' in module 'celery.task' ************* Module ips_quisitor.admin_dash.admin E1120: 49,8:CCAdmin.save_model: No value passed for parameter 'self' in function call ************* Module ips_quisitor.admin_dash.tasks E0611: 3,0: … -
Additional context for class based views through urlconf
I thought there was a simpler method of adding context through the urlconf but after having a look at the source this is what I came up with. Apparently there's only get_context_data() so I used a lambda to add what I needed. Update: I should probably have used extra_context={'model': 'Frontpage'} url( r'^$', TemplateView.as_view( template_name='pages/front.html', get_context_data=lambda: {'model': 'Frontpage'}, ), name='front', ), -
Additional context for class based views through urlconf
I thought there was a simpler method of adding context through the urlconf but after having a look at the source this is what I came up with. Apparently there's only get_context_data() so I used a lambda to add what I needed. Update: I should probably have used extra_context={'model': 'Frontpage'} url( r'^$', TemplateView.as_view( template_name='pages/front.html', get_context_data=lambda: {'model': 'Frontpage'}, ), name='front', ), -
Additional context for class based views through urlconf
I thought there was a simpler method of adding context through the urlconf but after having a look at the source this is what I came up with. Apparently there's only get_context_data() so I used a lambda to add what I needed. Update: I should probably have used extra_context={'model': 'Frontpage'} Raw url( r'^$', TemplateView.as_view( template_name='pages/front.html', get_context_data=lambda: {'model': 'Frontpage'}, ), name='front', ), -
Additional context for class based views through urlconf
I thought there was a simpler method of adding context through the urlconf but after having a look at the source this is what I came up with. Apparently there's only getcontextdata() so I used a lambda to add what I needed. <strong>Update</strong>: I should probably have used extra_context={'model': 'Frontpage'} Raw url( r'^$', TemplateView.as_view( template_name='pages/front.html', get_context_data=lambda: {'model': 'Frontpage'}, ), name='front', ), -
Дизайн API Я.ру
Вчера мы открыли в бету API для Я.ру. Это был первый пост в корпоративном блоге Яндекса с кодом на Питоне, что даже породило фан-арт :-). Для меня этот запуск имеет большое эмоциональное значение, потому что машиночитаемый веб — мой давний интерес, и этот проект — первый неигрушечный публичный API, где я занимаюсь дизайном, и могу смотреть, как выживают на практике теоретические соображения о том, как это должно делаться. Я говорю тут от своего лица, и чтобы не возникало ложных ощущений, должен сказать, что я это всё делаю, конечно, не один. Начинал писать собственно серверную часть Иван Челюбеев. Моя текущая роль — проектировщик и менеджер. Код пишет сейчас Костя Меренков, а со стороны Я.рушного бэкенда нам помогает Серёжа Чистович. Этот пост — несколько заметок о том, как всё устроено внутри. Пишите в комментариях, если что-то нужно раскрыть подробнее. Сервис над сервисом Сам Я.ру — многоуровневая кодобаза на нескольких языках и технологиях. Серверная её часть общается с внешним для себя миром по CORBA, и поэтому не подходит для публичного API. Кроме того, публичное API поддерживать тяжелее, чем внутреннее, из-за необходимости думать про обратную совместимость. Поэтому API сервиса Я.ру — это по сути ещё один отдельный сервис, который смотрит во внешний мир через … -
Going Mobile with Django and jQuery
Going Mobile with Django and jQuery -
An update to my Celery rant
An update to my rant on Celery’s frequently-changing API: I’ve decided to stay with Django-celery 2.5.5 and Celery 2.5.3. When I tried using Celery 3.0.4 with my existing code, Pylint threw about 60 warnings, many of which look real and all of which weren’t there when I used Celery 2.5.3. “Backwards-compatible” my ass! I shouldn’t have to chase my tail like this. Celery, you lost me. I’m now looking to replace you. Tagged: Django, Python -
Celery API changes drive me nuts
This is a rant. My company’s code base is over 65K lines of Python and JavaScript code. We use Celery, Django-Celery, and RabbitMQ for our background asynchronous tasks. Ten different tasks.py files contain 30 task classes, split roughly 50-50 between periodic and on-demand. We use subtasks. Today, I dug into updating from Celery 2.5.3 to 3.0.4, and I popped my cork. I am aggravated by the frequency and extent of Celery API changes. It’s easily changed more often than any other five technologies in our stack combined. I’ve been upgrading Celery and Django-celery every six months or so, which corresponds to upgrading every few minor versions. And the changes are similar in scope to what I see when upgrading any other technology across one or two major versions. Changes that may seem minor, like moving a class across modules (e.g., from celery.task.base to celery.app.task), are nontrivial when you have change lots of code. I might feel better if the edits gave my code some awesome new capabilities. But they don’t, so my internal reaction is, Why the <expletive> does this code have to change? Couldn’t the <unbelievably gross expletive involving a deformed farm animal> code have stayed where it <repeat … -
Django compressor and image preloading
Preface: Have you noticed how on some websites when you click on a link that opens a lightbox or any overlay for first time it takes some time to display the border/background/button images. Not quite fancy, right? This is because the load of this images starts at the moment the overlay is rendered on the screen. If this is your first load and these images are not in your browser cache it will take some time for the browser to retrieve them from the server. Solution: The solution for this is to preload the images i.e. to force the browser to request them from the server before they are actually used. With a simple javascript function and a list of the images URLs this is a piece of cake: $.preLoadImages = function() { var args_len = arguments.length; for (var i=0; i < args_len; i++) { var cacheImage = document.createElement('img'); cacheImage.src = arguments[i]; } } $.preLoadImages('/img/img1.png', '/img/img2.png') Please have in mind that the code above uses the jQuery library. Specialty: Pretty easy, but you have to hardcode the URLs of all images. Also if you are using Django compressor then probably you are aware that it adds extra hash to the … -
Do you check HTTPS certificates in your API clients?
Far from every API client checks HTTP Certificates by default. We need to educate each other to be safe! -
Django Update View without slug in the url
Today I wanted to use the Django Class Based View (CBV) UpdateView but without a slug identifier in the URL. For example, instead of /profiles/pydanny/ I would go to /my-crazy-profile/. Also, I needed to force authentication. I've done this with Django functional views a few times times, but today I did it in Django. This is what I did: 1. Added django-braces to my project Kenneth Love and Chris Jones' awesome django-braces package has some very handy mixins for working with Django CBVs. Kenneth and Chris really understand CBVs, specifically on how to extend them, and have provided a bunch of really useful utility methods in the django-braces library. Yeah, I could figure this stuff out on my own, but since those guys already did the hard work I might as well just lean on them. pip install django-braces==0.1.3 # settings.py INSTALLED_APPS = ( ... 'braces', ... ) 2. Wrote the view Assuming a very simple profile Model and Form (which they weren't - but that's not what this post is about), this is how I implemented the view: # profiles/views.py from django.views.generic import UpdateView from braces.views import LoginRequiredMixin # handles authentication from profiles.forms import ProfileForm from profiles.models import Profile … -
Django Update View without slug in the url
Today I wanted to use the Django Class Based View (CBV) UpdateView but without a slug identifier in the URL. For example, instead of /profiles/pydanny/ I would go to /my-crazy-profile/. Also, I needed to force authentication. I've done this with Django functional views a few times times, but today I did it in Django. This is what I did: 1. Added django-braces to my project Kenneth Love and Chris Jones' awesome django-braces package has some very handy mixins for working with Django CBVs. Kenneth and Chris really understand CBVs, specifically on how to extend them, and have provided a bunch of really useful utility methods in the django-braces library. Yeah, I could figure this stuff out on my own, but since those guys already did the hard work I might as well just lean on them. pip install django-braces==0.1.3 # settings.py INSTALLED_APPS = ( ... 'braces', ... ) 2. Wrote the view Assuming a very simple profile Model and Form (which they weren't - but that's not what this post is about), this is how I implemented the view: # profiles/views.py from django.views.generic import UpdateView from braces.views import LoginRequiredMixin # handles authentication from profiles.forms import ProfileForm from profiles.models import Profile … -
Orateurs, les rencontres django régionales ont besoin de vous !
L’un des résultats des discussions de la dernière DjangoCong fut de lancer l’idée de faire des DjangoCon régionales plus petites et qui permettraient de ne pas centraliser les attentes de toute la communauté sur un seul événement national. Et du coup d’éviter de générer de la frustration pour ceux qui n’ont pu acheter leurs billets et qui enragent, chez eux, parce qu’ils loupent la grand messe django FR. (pour avoir une idée de ce que cela peut donner, voir ce lien (oui je sais c’est un vieux lien, mais il est parfait pour la situation) ). Deux première initiatives ont été finalement été lancés : DjangoBreizh à Rennes (vive la Bretagne, le temps pourris, le cidre et les crêpes) le samedi 17 novembre. DjangoCon Toulouse (ils ont oublié un g à la fin du nom.. tss tss, mais bon vive le cassoulet) le 24 et 25 novembre. C’est avec une grande joie que j’ai vu naître ces deux initiatives locales (d’ailleurs je serais présent, d’une manière quasi certaine à Rennes et peut-être, mais vraiment peut-être à Toulouse). Parce que ce n’est pas forcément évident d’organiser des conférences, même ‘juste locale’. Et que même dans certains domaines, il me semble que … -
Django Update View without slug in the url
Today I wanted to use the Django Class Based View (CBV) UpdateView but without a slug identifier in the URL. For example, instead of /profiles/pydanny/ I would go to /my-crazy-profile/. Also, I needed to force authentication. I've done this with Django functional views a few times times, but today I did it in Django. This is what I did: 1. Added django-braces to my project Kenneth Love and Chris Jones' awesome django-braces package has some very handy mixins for working with Django CBVs. Kenneth and Chris really understand CBVs, specifically on how to extend them, and have provided a bunch of really useful utility methods in the django-braces library. Yeah, I could figure this stuff out on my own, but since those guys already did the hard work I might as well just lean on them. pip install django-braces==0.1.3 # settings.py INSTALLED_APPS = ( ... 'braces', ... ) 2. Wrote the view Assuming a very simple profile Model and Form (which they weren't - but that's not what this post is about), this is how I implemented the view: # profiles/views.py from django.views.generic import UpdateView from braces.views import LoginRequiredMixin # handles authentication from profiles.forms import ProfileForm from profiles.models import Profile … -
Redirect to Custom URL After Saving in Django Admin
Here's a quick and dirty admin hack that can save you *lots* of time if you're used to browsing between editing objects in admin and vieving the results on a live site. Put following `change_view`-method in your `admin.py` and now you can make links to admin change page that return you back to where you came from: ```python class BlogEntryAdmin(admin.ModelAdmin): ... def change_view(self, request, object_id, form_url='', extra_context=None): result = super(BlogEntryAdmin, self).change_view(request, object_id, form_url, extra_context) if request.GET.get('return_to', False): result['Location'] = request.GET['return_to'] return result ``` In your template you'd have something like: ```django {% if request.user.is_staff %} <a href="/admin/blog/blogentry/{{ entry.pk }}/?return_to={{ entry.get_absolute_url }}">Edit in admin</a> {% endif %} ``` Of course, if you're smart, you should convert any places that need this kind of functionality with frontend editing tools so you can forget going to the Admin in the first place. But meanwhile, those few lines of code may come in handy! -
Redirect to Custom URL After Saving in Django Admin
Here’s a quick and dirty admin hack that can save you lots of time if you’re used to browsing between editing objects in admin and vieving the results on a live site. Put following change_view-method in your admin.py and now you can make links to admin change page that return you back to where you came from: class BlogEntryAdmin(admin.ModelAdmin): ... def change_view(self, request, object_id, form_url='', extra_context=None): result = super(BlogEntryAdmin, self).change_view(request, object_id, form_url, extra_context) if request.GET.get('return_to', False): result['Location'] = request.GET['return_to'] return result In your template you’d have something like: {% if request.user.is_staff %} <a href="/admin/blog/blogentry/{{ entry.pk }}/?return_to={{ entry.get_absolute_url }}">Edit in admin</a> {% endif %} Of course, if you’re smart, you should convert any places that need this kind of functionality with frontend editing tools so you can forget going to the Admin in the first place. But meanwhile, those few lines of code may come in handy!