A reminder to myself » Python http://simionbaws.ro Stuff I might need later. Mon, 06 Jul 2015 13:25:52 +0000 en-US hourly 1 http://wordpress.org/?v=4.3.1 Django `CheckboxSelectMultiple` with `ModelMultipleChoiceField` generates too many queries (solution) http://simionbaws.ro/programming/django-checkboxselectmultiple-with-modelmultiplechoicefield-generates-too-many-queries/ http://simionbaws.ro/programming/django-checkboxselectmultiple-with-modelmultiplechoicefield-generates-too-many-queries/#comments Sat, 13 Sep 2014 11:57:18 +0000 http://simionbaws.ro/?p=388 If you use 
django.forms.ModelMultipleChoiceField
 with the default widget (
django.forms.widgets.SelectMultiple
 ), all’s good.

However, if you need to generate checkboxes for your choices, and use 

django.forms.widgets.CheckboxSelectMultiple
 you’ll notice that the field will generate alot of queries (one for each element in the queryset), which is really really bad. I personally ended up with hundred of queries.

Fix: add 

cache_choices=True
 to your 
django.forms.ModelMultipleChoiceField

Example:

Good practice:

test = forms.ModelMultipleChoiceField(
        queryset=MyModel.objects.all(),
        cache_choices=True,
        widget=forms.CheckboxSelectMultiple)

Bad practice:

test = forms.ModelMultipleChoiceField(
        queryset=MyModel.objects.all(),
        widget=forms.CheckboxSelectMultiple)

django-logo-negative

Google+
]]>
http://simionbaws.ro/programming/django-checkboxselectmultiple-with-modelmultiplechoicefield-generates-too-many-queries/feed/ 0
Django get current user globally in the project http://simionbaws.ro/programming/python-programming/django-python-programming/django-get-current-user-globally-in-the-project/ http://simionbaws.ro/programming/python-programming/django-python-programming/django-get-current-user-globally-in-the-project/#comments Fri, 23 May 2014 08:00:56 +0000 http://simionbaws.ro/?p=340 Sometimes, you will need to get the current authenticated user in models, or other parts of your app.

To achieve this, you must create this middleware and add it to MIDDLEWARE_CLASSES in project settings:

try:
    from threading import local, current_thread
except ImportError:
    from django.utils._threading_local import local

_thread_locals = local()


class GlobalUserMiddleware(object):
    """
    Sets the current authenticated user in threading locals

    Usage example:
        from app_name.middleware import get_current_user
        user = get_current_user()
    """
    def process_request(self, request):
        setattr(
            _thread_locals,
            'user_{0}'.format(current_thread().name),
            request.user)

    def process_response(self, request, response):

        key = 'user_{0}'.format(current_thread().name)

        if not hasattr(_thread_locals, key):
            return response

        delattr(_thread_locals, key)

        return response


def get_current_user():
    return getattr(
        _thread_locals,
        'user_{0}'.format(current_thread().name),
        None)

Usage example:

from myapp.middleware import get_current_user

user = get_current_user()

Google+
]]>
http://simionbaws.ro/programming/python-programming/django-python-programming/django-get-current-user-globally-in-the-project/feed/ 0
Invalidate template fragment cache in Django 1.5 http://simionbaws.ro/programming/python-programming/invalidate-template-fragment-cache-in-django-1-5/ http://simionbaws.ro/programming/python-programming/invalidate-template-fragment-cache-in-django-1-5/#comments Wed, 21 May 2014 13:23:23 +0000 http://simionbaws.ro/?p=335 Django 1.5 does not have a utility method to delete template fragment cache, with arguments.

In order to achieve this, you must create a custom method:

from django.core.cache import cache
from django.utils.hashcompat import md5_constructor
from django.utils.http import urlquote


def invalidate_template_fragment(fragment_name, *variables):
    args = md5_constructor(u':'.join([urlquote(var) for var in variables]))
    cache_key = 'template.cache.{0}.{1}'.format(fragment_name, args.hexdigest())
    cache.delete(cache_key)

Example usage:

{% cache 259200 key_name model_instance.pk %}
    ... cached content here ...
{% endcache %}

// note that "model_instance.pk" is optional argument. You can use as many as you need

… and delete the cache:

invalidate_template_fragment('key_name', model_instance.pk)

 

In django 1.6+ you can do this more easy:

from django.core.cache import cache
from django.core.cache.utils import make_template_fragment_key

key = make_template_fragment_key('key_name', [model_instance.pk])
cache.delete(key)

Google+
]]>
http://simionbaws.ro/programming/python-programming/invalidate-template-fragment-cache-in-django-1-5/feed/ 0
Manually generate Django password reset token http://simionbaws.ro/programming/manually-generate-django-password-reset-token/ http://simionbaws.ro/programming/manually-generate-django-password-reset-token/#comments Fri, 07 Mar 2014 10:18:17 +0000 http://simionbaws.ro/?p=210 Ever needed to manually generate a password reset token?

For example, imagine this situation:
You create a user from a custom form, and you want the user to set his own password.
Solution: generate a password reset token,  email him the link, and let him choose his own password.

Here’s how you implement this:

from django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_encode
from django.utils.encoding import force_bytes

from django.db.models.signals import post_save

post_save.connect(user_saved, User)

def user_saved(sender, instance, created, *args, **kwargs):
    if created:
        context = {
            'token': default_token_generator.make_token(instance),
            'uid': urlsafe_base64_encode(force_bytes(instance.pk)),
            'user': instance,
        }
        # here, send an email with this context

To display the link in the email, you must set the password reset url, and display it:

{% url 'password_reset_confirm' uidb64=uid token=token %}

urlpatterns += patterns(
    'django.contrib.auth.views',
    url(r'^password-change/done/$', 'password_change_done', name='password_change_done'),
    url(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
        'password_reset_confirm',
        name='password_reset_confirm'),
    url(r'^password-reset/done/$',
        'password_reset_done',
        name='password_reset_done'),
    url(r'^password-reset/complete/$',
        'password_reset_complete',
        name='password_reset_complete'),
)

 

Google+
]]>
http://simionbaws.ro/programming/manually-generate-django-password-reset-token/feed/ 0
Deploy with fabric on multiple servers http://simionbaws.ro/programming/deploy-with-fabric-on-multiple-servers/ http://simionbaws.ro/programming/deploy-with-fabric-on-multiple-servers/#comments Tue, 04 Mar 2014 10:06:52 +0000 http://simionbaws.ro/?p=200 Ever needed to deploy with fabric on multiple machines?
Here’s a simple solution to aproach this issue.

In your fabfile.py , add these two methods:

def live():
    global PATH, ENV_PATH
    env.hosts = ["22.2.222.2"]
    env.user = 'test'
    PATH = '/path/to/project'
    # optional, is using virtualenv
    ENV_PATH = '/path/to/virtualenv'
    # overwrite whatever variabled you need to change on the current machine

def staging():
    global PATH, ENV_PATH
    env.hosts = ["11.1.11.1"]
    env.user = 'test2'
    PATH = '/path/to/project/on/second/machine'
    # optional, is using virtualenv
    ENV_PATH = '/path/to/virtualenv'
    # overwrite whatever variabled you need to change on the current machine

Now, when deploying, for example:

def deploy():
    with cd(PATH), virtualenv(ENV_PATH):
        run('uber command')
        run('another uber command')

you must use the following commands, in the correct order:

#deploy on staging
fab staging deploy

# deploy on live
fab live deploy

Fabric runs the “staging” or “deploy” commands first, setting the envrinoment variables, and then it runs the “deploy” command doing whatever you asked it to do.

Google+
]]>
http://simionbaws.ro/programming/deploy-with-fabric-on-multiple-servers/feed/ 0
Pip PIL error: Could not find any downloads that satisfy the requirement PIL http://simionbaws.ro/programming/python-programming/pip-pil-error-could-not-find-any-downloads-that-satisfy-the-requirement-pil/ http://simionbaws.ro/programming/python-programming/pip-pil-error-could-not-find-any-downloads-that-satisfy-the-requirement-pil/#comments Tue, 14 Jan 2014 10:26:08 +0000 http://blog.simionbaws.ro/?p=167 When installing “PIL” with pip, I got this error:

Downloading/unpacking PIL
Could not find any downloads that satisfy the requirement PIL

 Fix: use “Pillow” instead of “PIL”. Make sure you uninstall PIL first.

pip uninstall PIL
pip install Pillow

 

Google+
]]>
http://simionbaws.ro/programming/python-programming/pip-pil-error-could-not-find-any-downloads-that-satisfy-the-requirement-pil/feed/ 0
Compare integer variable in django templates http://simionbaws.ro/programming/python-programming/compare-integer-variable-in-django-templates/ http://simionbaws.ro/programming/python-programming/compare-integer-variable-in-django-templates/#comments Tue, 07 Jan 2014 21:36:57 +0000 http://blog.simionbaws.ro/?p=141 Ever needed to compare some variable (that may come from db, forms, etc) in django templates with an integer?
Example:

{% if some_var == 3 %}
    working
{% endif %}

The above example will not work. Django’s template engine interprets the variable as a string.

Workaround for integer comparison:

{% if some_var|add:0 == 3 %}
    working
{% endif %}

By using the “add” filter, the variable is transformed into an integer.

Google+
]]>
http://simionbaws.ro/programming/python-programming/compare-integer-variable-in-django-templates/feed/ 6
Django emails with html/txt templates http://simionbaws.ro/programming/django-emails-with-htmltxt-templates/ http://simionbaws.ro/programming/django-emails-with-htmltxt-templates/#comments Thu, 10 Oct 2013 11:01:28 +0000 http://blog.simionbaws.ro/?p=100 Django Templated Email is a tool which sends email in django with html/txt templates.

Features:

  • Html / Txt templates
  • Context variables
  • Current site (from sites framework) available in templates as {{ site }} variable

Installation and usage:

Run the following command inside your django’s project directory

git submodule add https://github.com/simion/django-templated-email.git templated_email

  

In setting.py file add “templated_email” to INSTALLED_APPS

INSTALLED_APPS = (
    ...
    'templated_email',
    ...
)

Use the function. Example:

from templated_email import send_templated_email

...

send_templated_email(
    "Example subject"
    None,
    ['[email protected]']  #must be a list or tuple
    'example-template',
    context,  # context variables to send in template
    # cc = []
    # bcc = []
)

Don’t forget to create the template files.

In your templates folder, create a folder named ’email_templates’.

Place example-template.html or example-template.txt inside of it.

Example:

<project-path>/<app-path>/templates/email_templates/exmaple-template.html

 

]]>
http://simionbaws.ro/programming/django-emails-with-htmltxt-templates/feed/ 0
Loovea.com http://simionbaws.ro/stories/loovea-com-2/ http://simionbaws.ro/stories/loovea-com-2/#comments Mon, 26 Aug 2013 16:57:28 +0000 http://blog.simionbaws.ro/?p=46 Here’s an article I wrote (as a developer) from a very technical point of view, about Loovea.com

http://www.assist-software.net/blog/what-loovea-loovea-cool-social-network

Google+
]]>
http://simionbaws.ro/stories/loovea-com-2/feed/ 0