django

Add HTTP_REFERER in Django Test Client

I’m testing my views in my django project and got “None” error because my view returning redirect to “HTTP_REFERER” that I get from HTTP Header.

In django test client apparently all request does not contain any HTTP header.
Here is my views:

class DeleteCategoryView(TemplateView):

    def post(self, request, *args, **kwargs):
        ...
        return redirect(request.META.get('HTTP_REFERER'))

And here is how I add “HTTP_REFERER” in my test client.

def test_delete_view(self):
    url = reverse('category:url-adm-delete')
    redirect_url = reverse('category:url-adm-category')
    response = self.client.post(path=url, data={'id': instance.pk}, HTTP_REFERER=redirect_url)
    self.assertRedirects(response, index_url)

Reference: http://stackoverflow.com/a/11819426/1936697

Django Bootstrap Pagination Helper

I Just writing simple script for creating simple pagination with django and bootstrap.
To use these, what you need to do just add the middleware class to your settings.py, within you views just pass your queryset to the paginate function, then just include the html to you template.

Here is the usage example:

# views.py
class MemberView(TemplateView):
    template_name = 'persons/list.html'
    
    def get(self, request, *args, **kwargs):
        person_list = Person.objects.all()
        members = paginate(request=request, queryset=person_list, limit=30)

        context = self.get_context()
        context.update({
            'members': members
        })
        return super(MemberView, self).render_to_response(context)

# list.html
{% include 'paging.html' with paginator=members %}

NB: I assumed you are using twitter bootstrap on your project.

Custom Validator in Django Rest Framework Serializer

Here is how to create your own validator for your serializer fields.
For example I have serializer that it will accept image not large than 20MB.
There are 2 approach for this, we can use function or class based.

class ProfileSerializer(serializers.Serializer):
    profile_pict = serializers.ImageField()

Function based:

def validate_20mb_size(value):
    max_size = 1024 * 1024 * 20  # 20MB
    if value.size > max_size:
        raise serializers.ValidationError('Profile Image too large.')

# Then we use like this.
profile_pict = serializers.ImageField(validators=[validate_20mb_size])

Class based:

class ImageSizeValidator(object):
     def __init__(self, max_size):
        self.max_size = 1024 * 1024 * max_size

     def __call__(self, value):
        if value.size > self.max_size:
            raise serializers.ValidationError('Profile Image too large.')

# Then we use like this.
profile_pict = serializers.ImageField(validators=[ImageSizeValidator(max_size=20)])

You can use whatever you want depend on your needs, but I prefer to use class based because we can use the constructor to make the validator more generic and also inheritance. 😀

Reference: http://www.django-rest-framework.org/api-guide/validators/#writing-custom-validators

Django Fix Gunicorn Error “ImportError: No module named validation”

Today I’m trying to deploy django app to my VPS. I choose Gunicorn because their simple configuration. But when I run the wsgi server on gunicorn with this command.

$ gunicorn_django --bind mydomainOrvpsIp:8001

I got this error.

[2016-02-11 04:56:38 +0000] [15787] [ERROR] Exception in worker process:
Traceback (most recent call last):
  File "/root/.virtualenvs/portofolio/lib/python2.7/site-packages/gunicorn/arbiter.py", line 515, in spawn_worker
    worker.init_process()
  File "/root/.virtualenvs/portofolio/lib/python2.7/site-packages/gunicorn/workers/base.py", line 122, in init_process
    self.load_wsgi()
  File "/root/.virtualenvs/portofolio/lib/python2.7/site-packages/gunicorn/workers/base.py", line 130, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/root/.virtualenvs/portofolio/lib/python2.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/root/.virtualenvs/portofolio/lib/python2.7/site-packages/gunicorn/app/djangoapp.py", line 105, in load
    mod = util.import_module("gunicorn.app.django_wsgi")
  File "/root/.pyenv/versions/2.7.11/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/root/.virtualenvs/portofolio/lib/python2.7/site-packages/gunicorn/app/django_wsgi.py", line 21, in <module>
    from django.core.management.validation import get_validation_errors
ImportError: No module named validation

To fix this, we need to use latest command to run our app in gunicorn, because previous command already deprecated.

$ gunicorn --bind mydomainOrvpsIp:8001 myproject.wsgi:application

Reference: https://www.digitalocean.com/community/tutorials/how-to-deploy-a-local-django-app-to-a-vps?comment=12057