django.forms.ModelMultipleChoiceFieldwith 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.CheckboxSelectMultipleyou’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=Trueto 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)
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()
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)
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'), )
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.
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
{% 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.
Features:
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://www.assist-software.net/blog/what-loovea-loovea-cool-social-network