Django community: RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
Django 1.6 最佳实践: 编码风格
看到这个标题, 你很有可能会跳过这篇文章. 但我们认为只需要在编码时稍加注意, 良好的编码风格会影响颇深. 1. 代码可阅读性的重要性 代码写出来之后, 更多的时间是被阅读. 一段代码可能只用了几分钟就被写了出来, 几十分钟或几小时用来测试debug, 但可能一年或 几十年后都不会再被人修改. 恰恰, 当你或者别人一年或几十年后再阅读时, 一贯简洁的编码风格显得尤为重要. 它使得你不用去猜 想代码的不连续性, 使得大项目更容易维护, 使得小项目也更容易扩展. 那么, 怎么才算是良好的编码风格呢? 避免过度缩写的变量名 清晰的写出function传入参数(argument)的名字 为class和method写注释 重构代码: 将重复的代码提取出来, 写成function或method 保持function和method简短: 一个简单的规则是, 阅读一个function或method时, 不需要翻页 这样, 当重新接触长时间没有查看的代码时, 你会发现阅读和理解代码的时间会大大缩短. 例如, 当你读到一个名为 blance_sheet_decrease的变量时, 是不是比bsd或b_s_d这样的变量名更容易理解? 类似这样的缩写名, 虽然能在编写代码是为你节 省几秒钟, 但当重新阅读时, 可能耗费你几个小时. 因此这种缩写是不值得的! 2. PEP8 PPE 8是Python官方的代码风格指导. 我们建议你详细的阅读并使用这些规范: http://www.python.org/dev/peps/pep-0008/ 需要注意的是, PEP8只适用于新的项目, 如果将PEP8带入到已有项目时, 在有代码风格冲突时, 应保持原有规范, 以防发生混乱. 举些例子, PEP 8中定义的代码规范有: 每一等级的缩进使用4个空格 在最高级function和class前空两行 class中定义的method, 应该与前面的代码空一行 关于每行字符数限制 PEP8中, 规定了每行字符数的限制是79. 因为这是绝大多数编辑器和开发团队都能支持的字符数. 但PEP8中也有条款, 可将该限制扩展到99个字符数. 我们的理解是, 当该项目是开源时, 应尽量 将字符数控制在每行79个, 而当项目是闭源时, 则可以扩大到79个字符数. 3. 关于import 我们建议import按以下顺序排列: Python标准库 Django自带库 第三方App库 项目中App库 例如: # Python标准库 from __future__ import absolute_import from math import sqrt from os.path import abspath # Django自带库 from django.db import models from django.utils.translation import ugettext_lazy as _ # 第三方App库 from django_extensions.db.models import TimeStampedModel # 项目中App库 from .models import BananaSplit 使用明确指明的相对路径引用 当在写代码时, 应当时刻注意所写的代码应当能方便的移动, 重命名和升级. 在Python中, 使用明确指明的相对路径引用 (explicit relative import), 降低了模块之间的耦合性, 为我们带来了以上三个优点. 以上代码中的"from django_extensions.db.models import TimeStampedModel"便是一个很好的例子. 避免使用* 大多数情况下, 为了避免引起不可预料的混乱, 我们都不应该使用import *. 4. 其他 虽然在PEP8中没有明确指明, 但在实践中, 因尽量使用下划线"_", 而不是横杠"-", 因为下划线对于大多数IDE和文本编辑器都很友好. 但在URl中, 两者没有差别. -
Speeding up a Django web site without touching the code
I’ve recently been tweaking my server setup for a Django 1.3 web site with the goal of making it a bit faster. Of course, there is a lot of speed to gain by improving e.g. the number of database queries needed to render a web page, but the server setup also has an effect on the web site performance. This is a log of my findings. All measurements have been done using the ab tool from Apache using the arguments -n 200 -c 20, which means that each case have been tested with 20 concurrent requests up to 200 requests in total. The tests was run from another machine than the web server, with around 45ms RTT to the server. This is not a scientific measurement, but good enough to let me quickly test my assumptions on what increases or decreases performance. The Django app isn’t particularly optimized in itself, so I don’t care much about the low number of requests per second (req/s) that it manages to process. The main point here is the relative improvement with each change to the server setup. The baseline setup is a Linode 1024 VPS (Referral link: I get USD 20 off my … -
Comics v2.2.0 released with Django 1.5 support
Version 2.2.0 of my comics aggregator is now released. It features a general upgrade of dependencies, including the move from Django 1.4 to Django 1.5, and a lot of updates to comic crawlers. The Django upgrade was completed months ago and it’s been running my Comics instance since, so it’s about time to get it released before Django 1.6 arrives in a month or two. Regarding the crawler updates, it’s a bit sad to see that many of the crawlers have been broken for months without me or anybody else noticing, but it’s hard to catch some content lacking in the middle of a firehose of similar content. I guess I’ll have to make it a monthly task to look through the crawler status page of my Comics instance and do patch releases with updated crawlers. Check out the project docs for more information about Comics and this release in particular. -
Using PayPal WPS with Cartridge (Mezzanine / Django)
I recently built a web site using Mezzanine, a CMS built on top of Django. I decided to go with Mezzanine (which I've never used before) for two reasons: it nicely enhances Django's admin experience (plus it enhances, but doesn't get in the way of, the Django developer experience); and there's a shopping cart app called Cartridge that's built on top of Mezzanine, and for this particular site (a children's art class business in Sydney) I needed shopping cart / e-commerce functionality. This suite turned out to deliver virtually everything I needed out-of-the-box, with one exception: Cartridge currently lacks support for payment methods that require redirecting to the payment gateway and then returning after payment completion (such as PayPal Website Payments Standard, or WPS). It only supports payment methods where payment is completed on-site (such as PayPal Website Payments Pro, or WPP). In this case, with the project being small and low-budget, I wanted to avoid the overhead of dealing with SSL and on-site payment, so PayPal WPS was the obvious candidate. Turns out that, with a bit of hackery, making Cartridge play nice with WPS isn't too hard to achieve. Here's how you go about it. -
Creating web applications with Django and ember.js tutorial gets an update for latest ember.js version
My tutorial about creating ember.js applications with Django got updated to the latest ember.js version and the source code got published on github. I'm planning to write more about this framework soon, as now I'm spending a lot of time working with ember and Django, django-rest-framework and other interesting libraries. Aside of that I still have some topics on my ToDo list - Facebook apps related packages (future; when they get published), more Python + electronics tutorials, and Django/Python related (like checking Cherokee server or testing AppEnlight). What you find most interesting? -
Factor Your Django Settings Into uwsgi Ini Files
Although this is certainly not the usual use case for a Django site, I am deploying a new site that will be used by several programs at the school where I work. Each program will have its own specific Django settings file with its own values (for example, the database connection info) but for the most part the sites share a base settings_production.py file. Here is a sample of this file: from mysite.settings import * DEBUG = False TEMPLATE_DEBUG = DEBUG ALLOWED_HOSTS.append('.university.edu') INSTALLED_APPS.append( 'websso' ) MIDDLEWARE_CLASSES.append( 'django.contrib.auth.middleware.RemoteUserMiddleware' ) AUTHENTICATION_BACKENDS.append( 'websso.backends.RegistryRemoteUserBackend' ) DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': os.environ.get('MYSITE_DB_NAME'), 'USER': os.environ.get('MYSITE_DB_USER'), 'PASSWORD': os.environ.get('MYSITE_DB_PASSWORD'), 'HOST': os.environ.get('MYSITE_DB_HOST'), 'PORT': '5432', } } As you can see, we get the database connection values from the environment. I am using Apache (with mod_proxy_uwsgi) and uwsgi in emperor mode to run the site, and each site has a uwsgi ini file that actually sets all the relevant per-site settings via the env configuration option. This was quite easy to set up, and this is an example uwsgi ini file: [uwsgi] chdir=/srv/myvirtualenv/mysite module=mysite.wsgi:application max-requests=5000 socket=127.0.0.1:3032 logto=/tmp/uwsgi-example.log env = DJANGO_SETTINGS_MODULE=mysite.settings_production env = MYSITE_DB_NAME=mysite_dbname env = MYSITE_DB_USER=mysite_username env = MYSITE_DB_PASSWORD=abc123 env = MYSITE_DB_HOST=mysite-dbname.hostname.us-east-1.rds.amazonaws.com So far so good -- … -
Factor Your Django Settings Into uwsgi Ini Files
Although this is certainly not the usual use case for a Django site, I am deploying a new site that will be used by several programs at the school where I work. Each program will have its own specific Django settings file with its own values (for example, the database connection info) but for the most part the sites share a base settings_production.py file. Here is a sample of this file: from mysite.settings import * DEBUG = False TEMPLATE_DEBUG = DEBUG ALLOWED_HOSTS.append('.university.edu') INSTALLED_APPS.append( 'websso' ) MIDDLEWARE_CLASSES.append( 'django.contrib.auth.middleware.RemoteUserMiddleware' ) AUTHENTICATION_BACKENDS.append( 'websso.backends.RegistryRemoteUserBackend' ) DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': os.environ.get('MYSITE_DB_NAME'), 'USER': os.environ.get('MYSITE_DB_USER'), 'PASSWORD': os.environ.get('MYSITE_DB_PASSWORD'), 'HOST': os.environ.get('MYSITE_DB_HOST'), 'PORT': '5432', } } As you can see, we get the database connection values from the environment. I am using Apache (with mod_proxy_uwsgi) and uwsgi in emperor mode to run the site, and each site has a uwsgi ini file that actually sets all the relevant per-site settings via the env configuration option. This was quite easy to set up, and this is an example uwsgi ini file: [uwsgi] chdir=/srv/myvirtualenv/mysite module=mysite.wsgi:application max-requests=5000 socket=127.0.0.1:3032 logto=/tmp/uwsgi-example.log env = DJANGO_SETTINGS_MODULE=mysite.settings_production env = MYSITE_DB_NAME=mysite_dbname env = MYSITE_DB_USER=mysite_username env = MYSITE_DB_PASSWORD=abc123 env = MYSITE_DB_HOST=mysite-dbname.hostname.us-east-1.rds.amazonaws.com So far so good -- … -
Congrats to PearlHacks Winners (Including Our Intern, Annie)!
Caleb Smith, Caktus developer, awarding the third place prize to TheRightFit creators Bipasa Chattopadhyay, Ping Fu, and Sarah Andrabi. Many congratulations to the PearlHacks third place winners who won Sphero Balls! The team from UNC’s Computer Science department created TheRightFit, an Android app that helps shoppers know what sizes will fit them and their families among various brands. Their prize of Sphero Balls, programmable balls that can interact and play games via smart phones, was presented by Caktus developer and Pearl Hacks mentor Caleb Smith as part of our sponsorship. PearlHacks, held at UNC-Chapel Hill, is a conference designed to encourage female high school and college programmers from the NC and VA area. -
Congrats to PearlHacks Winners (Including Our Intern, Annie)!
Caleb Smith, Caktus developer, awarding the third place prize to TheRightFit creators Bipasa Chattopadhyay, Ping Fu, and Sarah Andrabi. Many congratulations to the PearlHacks third place winners who won Sphero Balls! The team from UNC’s Computer Science department created TheRightFit, an Android app that helps shoppers know what sizes will fit them and their families among various brands. Their prize of Sphero Balls, programmable balls that can interact and play games via smart phones, was presented by Caktus developer and Pearl Hacks mentor Caleb Smith as part of our sponsorship. PearlHacks, held at UNC-Chapel Hill, is a conference designed to encourage female high school and college programmers from the NC and VA area. Also, we’re deeply proud of our intern, Annie Daniel (UNC School of Journalism), who was part of the first place team for their application, The Culture of Yes. Excellent job, Annie! This is what Annie had to say about her team's first place project: The Culture of Yes was a web app that's meant to broaden the conversation on sexual assault on college campuses. We chose a flagship university from each of the 50 states, created a json file that summarized that university (population, male/female ratio, % … -
Reviewing Django REST Framework
Recently, we used Django REST Framework to build the backend for an API-first web application. Here I’ll attempt to explain why we chose REST Framework and how successfully it helped us build our software. Why Use Django REST Framework? RFC-compliant HTTP Response Codes Clients (javascript and rich desktop/mobile/tablet applications) will more than likely expect your REST service endpoint to return status codes as specified in the HTTP/1.1 spec. Returning a 200 response containing {‘status’: ‘error’} goes against the principles of HTTP and you’ll find that HTTP-compliant javascript libraries will get their knickers in a twist. In our backend code, we ideally want to raise native exceptions and return native objects; status codes and content should be inferred and serialised as required. If authentication fails, REST Framework serves a 401 response. Raise a PermissionDenied and you automatically get a 403 response. Raise a ValidationError when examining the submitted data and you get a 400 response. POST successfully and get a 201, PATCH and get a 200. And so on. Methods You could PATCH an existing user profile with just the field that was changed in your UI, DELETE a comment, PUT a new shopping basket, and so on. HTTP methods exist … -
First impressions of Django 1.7 beta upgrade in a young project
Since few days we have Django 1.7 beta, which brings many changes including built in migrations system. At the company we have one quite new project that is still in development so we decided to use it as a guinea pig and use Django 1.7b1 for it. The upgrade from 1.6 wasn't that problematic, but it required some search-and-fix actions... -
玩转Django1.7的新功能之Schema migrations
上周 Django 1.7 beta 1 released,这是Django 1.7正式版发布周期的一个重要里 […] -
Django-filter and custom querysets
Django-filter is a powerful tool, but the documentation is a little sparse. If you want to see examples of custom Filters you have to dive into the source code. I recently wanted to add a filter for methods on a custom QuerySet. Unlike custom managers, custom QuerySets allow you to chain methods. You can read this introduction or refer to the official documentation (at the time of this writing 1.7 wasn't released yet). Here is a short example of what's possible: Product.products.in_stock().price_below(100).has_color('red') You get the idea, it's just a convenient way to write shorter code. So I had my methods and wanted to use them with django-filter, but it took a while to figure out how. After some digging I took the DateRangeField class as a blueprint (0.7 source) and came up with this filter: class QuerySetFilter(django_filters.ChoiceFilter): def __init__(self, options, *args, **kwargs): self.options = options kwargs['choices'] = [ (key, value[0]) for key, value in six.iteritems(self.options)] super(QuerySetFilter, self).__init__(*args, **kwargs) def filter(self, qs, value): config = self.options[value][1] method = config.get('method', '') args = config.get('args', ()) kwargs = config.get('kwargs', {}) if method == '': return qs elif not hasattr(qs, method): raise Exception("Improperly configured", "Unknown QuerySet method %s" % method) return getattr(qs, method)(*args, **kwargs) … -
Django-filter and custom querysets
Django-filter is a powerful tool, but the documentation is a little sparse. If you want to see examples of custom Filters you have to dive into the source code. I recently wanted to add a filter for methods on a custom QuerySet. Unlike custom managers, custom QuerySets allow you to chain methods. You can read this introduction or refer to the official documentation (at the time of this writing 1.7 wasn't released yet). Here is a short example of what's possible: Product.products.in_stock().price_below(100).has_color('red') You get the idea, it's just a convenient way to write shorter code. So I had my methods and wanted to use them with django-filter, but it took a while to figure out how. After some digging I took the DateRangeField class as a blueprint (0.7 source) and came up with this filter: class QuerySetFilter(django_filters.ChoiceFilter): def __init__(self, options, *args, **kwargs): self.options = options kwargs['choices'] = [ (key, value[0]) for key, value in six.iteritems(self.options)] super(QuerySetFilter, self).__init__(*args, **kwargs) def filter(self, qs, value): method = self.options[value][1]['method'] if 'args' in self.options[value][1]: args = self.options[value][1]['args'] else: args = () if 'kwargs' in self.options[value][1]: kwargs = self.options[value][1]['kwargs'] else: kwargs = {} if method == '': return qs elif not hasattr(qs, method): raise Exception("Improperly configured", … -
Django-filter and custom querysets
Django-filter is a powerful tool, but the documentation is a little sparse. If you want to see examples of custom Filters you have to dive into the source code. I recently wanted to add a filter for methods on a custom QuerySet. Unlike custom managers, custom QuerySets allow you to chain methods. You can read this introduction or refer to the official documentation (at the time of this writing 1.7 wasn't released yet). Here is a short example of what's possible: Product.products.in_stock().price_below(100).has_color('red') You get the idea, it's just a convenient way to write shorter code. So I had my methods and wanted to use them with django-filter, but it took a while to figure out how. After some digging I took the DateRangeField class as a blueprint (0.7 source) and came up with this filter: class QuerySetFilter(django_filters.ChoiceFilter): def __init__(self, options, *args, **kwargs): self.options = options kwargs['choices'] = [ (key, value[0]) for key, value in six.iteritems(self.options)] super(QuerySetFilter, self).__init__(*args, **kwargs) def filter(self, qs, value): config = self.options[value][1] method = config.get('method', '') args = config.get('args', ()) kwargs = config.get('kwargs', {}) if method == '': return qs elif not hasattr(qs, method): raise Exception("Improperly configured", "Unknown QuerySet method %s" % method) return getattr(qs, method)(*args, **kwargs) … -
Using tox with Django projects
Today I was adding tox and Travis-CI support to a Django project, and I ran into a problem: our project doesn’t have a setup.py. Of course I could have added one, but since by convention we don’t package our Django projects (Django applications are a different story) – instead we use virtualenv and pip requirements files - I wanted to see if I could make tox work without changing our project. Turns out it is quite easy: just add the following three directives to your tox.ini. In your [tox] section tell tox not to run setup.py: skipsdist = True In your [testenv] section make tox install your requirements (see here for more details): deps = -r{toxinidir}/dev-requirements.txt Finally, also in your [testenv] section, tell tox how to run your tests: commands = python manage.py test Now you can run tox, and your tests should run! For reference, here is a the complete (albeit minimal) tox.ini file I used: [tox] envlist = py27 skipsdist = True [testenv] deps = -r{toxinidir}/dev-requirements.txt setenv = PYTHONPATH = {toxinidir}:{toxinidir} commands = python manage.py test The post Using tox with Django projects appeared first on David Murphy. -
The limits of "unlimited" vacation
Obligatory Disclaimer: this post discusses unlimited vacation policies. My employer (Heroku) has one such policy. However, this post isn’t really specifically about Heroku’s policy; it’s about the concept in general, not any specific implementation. As is always the case, on this site I speak for myself, not my company or anyone else. Many companies, especially tech companies, have adopted “unlimited” vacation policies — instead of a set number of days of paid time off (PTO), employees are told something along the lines “take as much time as you need”. -
Using django-tables2, django-filter and django-crispy-forms together
I was recently working on a very CRUDy prototype and decided to use some Django applications and tools together I hadn't combined yet: Django-tables2, an excellent application that allows you to quickly build tables Django-filter for easy filtering Django-crispy-forms for easy form creation A view that uses all three apps together could look like this: from django.views.generic import TemplateView from django_tables2 import RequestConfig # Your write the four classes imported below # (and pick a better location) from foo.models import Foo from foo.models import FooFilter from foo.models import FooTable from foo.models import FooFilterFormHelper class FooTableView(TemplateView): template_name = 'app/foo_table.html' def get_queryset(self, **kwargs): return Foo.objects.all() def get_context_data(self, **kwargs): context = super(FooTableView, self).get_context_data(**kwargs) filter = FooFilter(self.request.GET, queryset=self.get_queryset(**kwargs)) filter.form.helper = FooFilterFormHelper() table = FooTable(filter.qs) RequestConfig(self.request).configure(table) context['filter'] = filter context['table'] = table return context While this is a basic example there's still a lot going on. The get_context_data() method gets called automatically by the TemplateView and populates the template context with the filter and table objects. At first the code creates an instance of your FooFilter (django_filters.FilterSet) and passes it the request's GET data, and the queryset to work on. The filter does what you'd expect and filters the queryset. The filter object also includes … -
Using django-tables2, django-filters and django-crispy-forms together
I was recently working on a very CRUDy prototype and decided to use some Django applications and tools together I hadn't combined before: Django-tables2, an excellent application that allows you to quickly build tables Django-filter for easy filtering Django-crispy-forms for easy form creation A view that uses all three apps together could look like this: class FooTableView(TemplateView): template_name = 'myapp/foo_list.html' def get_queryset(self): return Foo.objects.all() def get_context_data(self, **kwargs): context = super(FooTableView, self).get_context_data(**kwargs) filter = FooFilter(self.request.GET, queryset=self.get_queryset()) filter.form.helper = FooFilterFormHelper() table = FooTable(filter.qs) RequestConfig(self.request).configure(table) context['filter'] = filter context['table'] = table return context While this is a basic example there's still a lot going on. The get_context_data method gets called automatically by the TemplateView and populates that template context with our filter and table objects. At first we create an instance of FooFilter and pass it the request's GET data, and the queryset to work on. The filter does what you'd expect and filters the queryset. The filter object also includes a form that's used to filter the data. We inject a crispy form helper to style the form. At last we create the table object based on our filtered queryset and configure it. Displaying everything on the frontend now becomes as easy … -
Using django-tables2, django-filter and django-crispy-forms together
I was recently working on a very CRUDy prototype and decided to use some Django applications and tools together I hadn't combined yet: Django-tables2, an excellent application that allows you to quickly build tables Django-filter for easy filtering Django-crispy-forms for easy form creation A view that uses all three apps together could look like this: from django.views.generic import TemplateView from django_tables2 import RequestConfig # Your write the four classes imported below # (and pick a better location) from foo.models import Foo from foo.models import FooFilter from foo.models import FooTable from foo.models import FooFilterFormHelper class FooTableView(TemplateView): template_name = 'app/foo_table.html' def get_queryset(self, **kwargs): return Foo.objects.all() def get_context_data(self, **kwargs): context = super(FooTableView, self).get_context_data(**kwargs) filter = FooFilter(self.request.GET, queryset=self.get_queryset(**kwargs)) filter.form.helper = FooFilterFormHelper() table = FooTable(filter.qs) RequestConfig(self.request).configure(table) context['filter'] = filter context['table'] = table return context While this is a basic example there's still a lot going on. The get_context_data() method gets called automatically by the TemplateView and populates the template context with the filter and table objects. At first the code creates an instance of your FooFilter (django_filters.FilterSet) and passes it the request's GET data, and the queryset to work on. The filter does what you'd expect and filters the queryset. The filter object also includes … -
KnockoutJS HTML binding
TL;DR: Don't use KnockoutJS ``html`` binding lots of times in your page. I'm in the middle of rewriting a large part of our application in HTML: for a lot of the interactivity stuff, anything more than just a simple behaviour, I'm turning to KnockoutJS. Mostly, it's been awesome. Being able to use two-way binding is the obvious big winner, but dependency tracking is also fantastic. However, I have had some concerns with performance in the past, and this was always on my mind as I moved into quite a complicated part of the system. Our approach is that we are not creating a single page application: different parts of the system are at different URLs, and visiting that page loads up the relevant javascript. This is a deliberate tradeoff, mostly because for the forseeable future, our software will not work without a connection to our server: most of the logic related to shift selection is handled by that. We aren't about to change that. While rewriting the rostering interface, I initially had Django render the HTML, and I added behaviours. This was possible, and quite fast, however as the behaviours became more complex, I was doing things like sending back … -
Django Class-Based Generic Views: tips for beginners (or things I wish I’d known when I was starting out)
Django is renowned for being a powerful web framework with a relatively shallow learning curve, making it easy to get into as a beginner and hard to put down as an expert. However, when class-based generic views arrived on the scene, they were met with a lukewarm reception from the community: some said they were too difficult, while others bemoaned a lack of decent documentation. But if you can power through the steep learning curve, you will see they are also incredibly powerful and produce clean, reusable code with minimal boilerplate in your views.py. So to help you on your journey with CBVs, here are some handy tips I wish I had known when I first started learning all about them. This isn’t a tutorial, but more a set of side notes to refer to as you are learning; information which isn’t necessarily available or obvious in the official docs. Starting out If you are just getting to grips with CBVs, the only view you need to worry about is TemplateView. Don’t try anything else until you can make a ‘hello world’ template and view it on your dev instance. This is covered in the docs. Once you can handle … -
Memories of Malcolm
A year ago today Malcolm Tredinnick, core contributor to Django suddenly passed away. He was a mentor, and more importantly, a good friend. Here are some of my memories of Malcolm. DjangoCon US: September 2010 This is where Audrey and I first met Malcolm. We ended up spending a good amount of the conference with him just hanging out and having a good time. I remember being honored that such a luminary wanted to spend time with us, yet was more delighted in discovering a good friend. During the conference, he peered into the nascent code base of djangopackages.com and asked some pointed questions. We justified a few design decisions, and he agreed, and we saw him using similar techniques later. He gave us some great pointers on things we could do, and I believe we implemented all of them. Summer to Autumn of 2010 Malcolm and I worked together on a project in 2010. During this time we had a number of email and chat discussions. Going over them now I'm impressed by his friendship and generosity of knowledge. I know he was terribly busy but yet he always had time for me in 2010. After about 15 emails … -
Memories of Malcolm
A year ago today Malcolm Tredinnick, core contributor to Django suddenly passed away. He was a mentor, and more importantly, a good friend. Here are some of my memories of Malcolm. DjangoCon US: September 2010 This is where Audrey and I first met Malcolm. We ended up spending a good amount of the conference with him just hanging out and having a good time. I remember being honored that such a luminary want to spend time with us, yet more importantly discovering a good friend. During the conference, he peered into the nascent code base of djangopackages.com and asked some pointed questions. We justified a few design decisions, and he nodded and we saw him using similar techniques later. He also gave us some great pointers on things we could do, and I believe we implemented all of them. Summer to Autumn of 2010 Malcolm and I worked together on a project in 2010. During this time we had a number of email and chat discussions. Going over them now I'm impressed by his friendship and generosity of knowledge. I know he was terribly busy but yet he always had time for me in 2010. After about emails where I … -
Better Models Through Custom Managers and QuerySets
Learn what it takes to get common queries chain-able, and slimmer. This video goes over custom model managers and custom querysets so you can write better code, cleaner, code by harnessing the power of Django and OOP.Watch Now...