How to fix slow file read/write in Node.js

This morning, I had trouble with one of my grunt tasks taking several minutes to finish instead of 3-4 seconds. After a bit of troubleshooting, I isolated the bottleneck to a bunch of seemingly harmless file reads.

Guess who was the culprit? The company-supplied McAfee. Turning off on-access scan immediately fixed the issue and dropped the build time from 3 minutes to 5 seconds.

Django DeleteView with AJAX

The default Django generic DeleteView is not perfectly adapted for AJAX requests. A much simpler AjaxDeleteView can easily be implemented using the same mixins as Django’s generic class-based views:

class AjaxDeleteView(SingleObjectMixin, View):
    """
    Works like DeleteView, but without confirmation screens or a success_url.
    """
    def post(self, *args, **kwargs):
        self.object = self.get_object()
        self.object.delete()
        return HttpResponse(status=204)

This views performs CSRF validation just like the default DeleteView, except it won’t show any confirmation screens and has no need for the success_url attribute.

Return a user’s own objects with Django’s class-based views

There is a very simple way to only return the connected user’s own objects with Django’s generic class-based views.

When you extend get_queryset() on any view that implements SingleObjectMixin or MultipleObjectMixin (almost all of them), you can filter the default QuerySet to match your needs. It becomes fairly easy to create a mixin that filters any queryset to return objects created by the current user.

This is the mixin we will be using:

class OwnObjectsMixin():
    """
    Only returns objects that belongs to the current user. Assumes the object
    has a 'user' foreignkey to a User.
    """
    def get_queryset(self):
        user = self.request.user
        return super(OwnObjectsMixin, self).get_queryset().filter(user=user)

Let’s say you have a Bookmark model that has a foreign key called user that points to the standard User model. UserList view would look like this:

class UserList(OwnObjectsMixin, ListView):
    model = User

class UserDetails(OwnObjectsMixin, DetailView):
    model = User

You can use that mixin with CreateView, DeleteView and UpdateView too, making your views simple and maintainable.

Pagination with Django’s generic ListView

Did you know the Django ListView supports pagination out of the box? All you need to do is specify the number of items per page with the paginate_by attribute:

class ArticleList(ListView):
    model = Article
    paginate_by = 10

The queryset available in object_list will be paginated, so you will only get 10 results. page_obj and paginator will be added to the context so you can have pagination buttons and know which page you are on.

The documentation for this is buried under MultipleObjectMixin’s documentation.

A heap implementation in Python

One more python implementation of a data structure. This is a heap implementation that follows an architecture similar to the binary search tree we have built earlier.

from collections import Container

class Heap(Container):
    array = []

    # Allows "if item in tree:"
    def __contains__(self, item):
        return self._contains(item, 1)

    def _contains(self, item, index):
        if item > self.array[index-1]:
            return False
        elif item < self.array[index-1]:
            if len(self.array) > index * 2:
                return self._contains(item, index*2) or self._contains(item, index*2+1)
            elif len(self.array) > index * 2 + 1:
                return self._contains(item, index*2)
            else:
                return False
        else:
            return True

    def add(self, item):
        self.array.append(item)
        self._bubble(len(self.array)-1)

    def _bubble(self, index):
        # Note: we take 1-based indexes, but convert them to 0-based ones
        index = index-1
        if self.array[index] > self.array[index/2]:
            tmp = self.array[index]
            self.array[index] = self.array[index/2]
            self.array[index/2] = tmp
            self._bubble(index/2)

    # Useful for debugging. Prints the whole tree
    def __repr__(self):
        return self._repr(1)

    def _repr(self, index, indent=0):
        # Note: we use 1-based indexes here
        string = ""
        string = ('\t' * indent) + str(self.array[index-1]) + '\n'

        if len(self.array) >= index * 2:
            string += ('\t' * (indent+1)) + 'Left:\n'
            string += self._repr(index*2, indent+1)

        if len(self.array) >= index * 2 + 1:
            string += ('\t' * (indent+1)) + 'Right:\n'
            string += self._repr(index*2+1, indent+1)

        return string

You can reuse the same code as the last time to test it:

from random import randint

# Add random values
values = []
tree = Heap()
for i in range(40):
    val = randint(0,100)
    tree.add(val)
    values.append(val)

print(tree)  # uses __repr__
print(values)
print(25 in tree)  # uses __contains__
print(25 in values)

A binary search tree in Python

As part of my series on concepts you should never, ever need to reimplement in a real world scenario, here is a binary search tree in Python. This particular example contains a bit of duplicate code, but I doubt the benefits of changing this would outweigh the loss in readability, especially for a learning example.

For the sake of doing things correctly, we extend collections.Container, a Python abstract class shared by most other collections.

from collections import Container
class Node(object):
    left = None
    right = None
    value = None

class BinarySearchTree(Container):

    root = Node()

    # Allows "if item in tree:"
    def __contains__(self, item):
        return self._contains(item, self.root)

    def _contains(self, item, node):
        if item > node.value:
            if node.right:
                return self._contains(item, node.right)
            else:
                return False

        elif item < node.value:
            if node.left:
                return self._contains(item, node.left)
            else:
                return False

        else:
            return True

    def add(self, item):
        self._add(item, self.root)

    def _add(self, item, node):
        if node.value:
            if item > node.value:
                if node.right:
                    self._add(item, node.right)
                else:
                    node.right = Node()
                    node.right.value = item
            elif item < node.value:
                if node.left:
                    self._add(item, node.left)
                else:
                    node.left = Node()
                    node.left.value = item
            else:  # Node does not exist or has same value as item
                node = Node()
                node.value = item
        else:
            node.value = item

    # Useful for debugging. Prints the whole tree
    def __repr__(self):
        return self._repr(self.root)

    def _repr(self, node, indent=0):
        string = ('\t' * indent) + str(node.value) + '\n'

        if node.left:
            string += ('\t' * (indent+1)) + 'Left:\n'
            string += self._repr(node.left, indent+1)
        if node.right:
            string += ('\t' * (indent+1)) + 'Right:\n'
            string += self._repr(node.right, indent+1)

        return string

And now we can test our tree:

from random import randint

# Add random values
values = []
tree = BinarySearchTree()
for i in range(40):
    val = randint(0,100)
    tree.add(val)
    values.append(val)

print(tree)  # uses __repr__
print(values)
print(25 in tree)  # uses __contains__
print(25 in values)