When you modify your settings.py file of your Django project on production servers you can get errors like this when updating the code:
$ git fetch $ git merge origin/master ... error: Your local changes to 'settings.py' would be overwritten by merge. Aborting. Please, commit your changes or stash them before you can merge. ...
The best solution I’ve found was using the stash, a temporary location where you can save your changes to recover them later, resetting your branch to put it in a clean state.
$ git stash save "My local settings.py prod changes"
Saved working directory and index state On master: My local settings.py prod changes
HEAD is now at a318301 That commit message
$ git merge origin/master
Merge made by recursive.
...
5 files changed, 219 insertions(+), 28 deletions(-)
...
$ git stash list
stash@{0}: On master: My local settings.py prod changes
$ git stash apply
Auto-merging settings.py
...
$ git stash drop
Dropped refs/stash@{0} (c00440c6a495cffd2f69de172faf6371c28058cf)
And your changes are back again!
// Symfony 2
public function updateAction($id)
{
$em = $this->getDoctrine()->getEntityManager();
$product = $em->getRepository('AcmeStoreBundle:Product')->find($id);
if (!$product) {
throw $this->createNotFoundException('No product found for id '.$id);
}
$product->setName('New product name!');
$em->flush();
return $this->redirect($this->generateUrl('homepage'));
}
# Django
def updateAction(request, id):
product = Product.objects.get(pk=id)
# Product.DoesNotExist exception raised if not found
product.name = u"New product name!"
product.save()
return HttpResponseRedirect(reverse('homepage'))
Now that we know how to trigger django permission creation mechanism with a fake migration, there is still one more issue. Those permissions are not associated to the right content_type (the one that corresponds to the proxy models), so they are useless in the django admin.
This is related to an old bug in django, by which , when creating a proxy model, the content type object associated to it was the same that the proxy model’s parent, but the admin permission system works using the app_name, so there is a contradiction in there.
On django 1.3 (I can’t tell for earlier versions), there is a new content type object created per each proxy model, but the automatic permissiion creation mechanism doesn’t work right with that. Django keeps creating permissions for the proxy model’s parent class, and the admin framework keeps needing more specific permissions to allow someone in. This is related to the ContentTypeManager.get_for_model(class) method.
Well, there’s a hack I got from modifying this ticket attachment.:
Say you put all of your proxy models under an app called “customer”, so the “customers” can access a “special admon” in which you can customize several options without having to mutilate your own admon.
What we do is disconnect the default “create_permissions” function from the post_syncdb signal, connect it to our very own custom function, and, in case the “sender” of the signal is other than our particular app (which we know contains only proxy models), then use the old “create_permissions”funcion.
I put this in my customer/models.py
from django.db.models import get_models
from django.db.models.signals import post_syncdb
from django.utils.encoding import smart_unicode
from django.contrib.auth.management import create_permissions, _get_all_permissions
# Hack the postsyncdb signal, so we can fix the misbehavior of the
# content_type
# assignment to the proxy models.
# see http://code.djangoproject.com/ticket/11154
def create_permissions_respecting_proxy(
app, created_models, verbosity, **kwargs
):
if not kwargs['sender'].__name__ == 'customer.models':
# if not in 'customer' app, then use the original function
create_permissions(app, created_models, verbosity, **kwargs)
return
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import models as auth_app
app_models = get_models(app)
searched_perms = list()
ctypes = set()
for klass in app_models:
# this is where the difference is: the original create_permissions
# use ctype = ContentType.objects.get_for_model(klass)
opts = klass._meta
ctype, created = ContentType.objects.get_or_create(
app_label=opts.app_label,
model=opts.object_name.lower(),
defaults = {'name': smart_unicode(opts.verbose_name_raw)}
)
# end of the modification
ctypes.add(ctype)
for perm in _get_all_permissions(klass._meta):
searched_perms.append((ctype, perm))
all_perms = set(auth_app.Permission.objects.filter(
content_type__in=ctypes
).values_list("content_type", "codename"))
for ctype, (codename, name) in searched_perms:
if(ctype.pk, codename) in all_perms:
continue
p = auth_app.Permission.objects.create(
codename=codename, name=name, content_type=ctype
)
if verbosity >=2:
print "Adding permission '%s'" % p
post_syncdb.disconnect(
create_permissions,
dispatch_uid='django.contrib.auth.management.create_permissions',
)
post_syncdb.connect(
create_permissions_respecting_proxy,
dispatch_uid='django.contrib.auth.management.create_permissions',
)
enjoy.
For those of you that use Textmate here are my favourite bundles and plugins. First of all you should read documentation on how to get more bundles.
GetBundles
This bundle lets you easily find and install other bundles. It’s not so pretty but it works. You can download it with this Terminal.app command:
svn export http://svn.textmate.org/trunk/Review/Bundles/GetBundles.tmbundle
Open the working directory in Finder (open .) and double click the .tmbundle to install it.
You can access GetBundles from the Bundles menu. You will get a window where you will find lots of bundles for different purposes. Sometimes you will find different bundles for the same purpose. It’s up to you to download and install the one that best fit to your workflow.
LESS TextMate Bundle (by Carter Allen)
You can install it from GetBundles. It will save a .css file in the same directory of your .less file, making development easier. It requires the LESS library:
sudo gem install less
And that’s it.
Django Bundles
I use the official Python Django bundle and the Python Django Templates bundle by Paul Bissex. You can install them from GetBundles. They will make your life easier if you develop in Django. They support most of the commonly used syntax for models, templates…
AckMate
This is the Textmate’s Find in Project command with steroids. It shows you what file contains what you were searching for and a small piece of the code around the result with line numbers. You can download it from protocool’s GitHub. I’ve downloaded the 1.1.1 version because of some UTF-8 issues in 1.1.2.
If you have binary files not recognized by ack you will get lots of errors (PDF files, for example). You can edit a .ackrc file in your home directory and put your binary file extensions like this:
--type-set=bin=.pdf .pyc --nobin
The first line defines the bin type for .pdf and .pyc extensions and the second line deactivates those types in for ack.
For all of you that don’t know what Less CSS is, check this first, but I will try to summarize it in a phrase:
It is a way of writing cleaner CSS code using variables and mixins but with the need of being compiled to an actual CSS file.
Lets see an example of .less file:
@corporate-red: #c00;
a {
color: @corporate-red;
}
... (1000 lines of code later) ...
blockquote em {
color: @corporate-red;
}
After compiling it would become:
a {
color: #cc0000;
}
... (1000 lines of code later) ...
blockquote em {
color: #cc0000;
}
With the advantage that, if we change the value of @corporate-red to #900 we can re-compile and go on, changing only one value.
Ok, ¿how we do benefit of this wonder in symfony?
There are multiple plugins and libraries for symfony but I’m a idle for some things. My quick & dirty solution is not the best because I must update all libs manually, but it was only an experiment that someone less idle than me can use to develop a great updateable symfony plugin.
I used:
First I got the lessphp’s lessc class file (lessc.inc.php) and renamed it to lessc.class.php and moved it into my sf project’s lib directory.
Later I supposed that I could have my .less and my .css files in the same folder and use .less files in development environment and compiled .css files in production so I’ve created a task to recompile manually all .less files in my /css folder.
// lib/task/compileLessTask.class.php
class compileLessTask extends sfBaseTask
{
protected function configure()
{
$this->namespace = "less";
$this->name = "compile";
$this->briefDescription = "Compile all .less files into .css files";
}
protected function execute($arguments = array(), $options = array())
{
$dir = sfConfig::get('sf_web_dir')."/css";
// Exclude all *.inc.less from compile
$lessfiles = sfFinder::type('file')
->not_name('*.inc.less')->name('*.less')
->in($dir);
$compiler = new lessc();
$compiler->importDir = $dir."/includes/";
foreach($lessfiles as $lessfile)
{
echo "Compiling ".basename($lessfile).PHP_EOL;
try
{
file_put_contents(dirname($lessfile)."/".basename($lessfile, '.less').".css", $compiler->parse(file_get_contents($lessfile)));
}
catch (Exception $e)
{
echo "Less fatal error: ".$e->getMessage().PHP_EOL;
}
}
}
}
So I can run $ php symfony less:compile in my terminal after a development session.
And finally, we must load different stylesheets if we are in dev environment than in other cases, so I created a LessHelper.php file in my apps/myapp/lib/helper directory:
function use_less_stylesheet($css, $position = '', $options = array())
{
if ("dev" == sfConfig::get('sf_environment'))
{
use_javascript('less-1.0.35.min.js', 'last');
use_stylesheet(basename($css, '.css').".less", $position, array_merge($options, array('rel' => 'stylesheet/less')));
}
else
{
use_stylesheet(basename($css, '.less').".css", $position, $options);
}
}
As you can see I’ve added the LessJS file to my /js folder and loaded the in dev environment.
The problem here is that I cannot get this working through the app-level view.yml file so I’ve done it through a helper taking advantage of the fact that the configuration of assets in view.yml is deprecated in favor of use_javascript and use_stylesheet helpers.
Suppose you’ve done all of this and I forgot nothing, and suppose you have a layout.less file in /css folder and lessjs in /js folder. You would have something like this:
/apps/myapp/lib/helper/LessHelper.php /apps/myapp/templates/layout.php /lib/lessc.class.php /lib/task/compileLessTask.class.php /web/css/layout.less /web/js/less-1.0.35.min.js
And in your layout.php you’ve added:
<?php
use_helper('Less');
use_less_stylesheet('layout');
?>
Then if you access your production environment, symfony will add the following line to your document’s head section:
<link rel="stylesheet" type="text/css" media="screen" href="/css/layout.css">
And if you access your dev environment:
... <link rel="stylesheet/less" type="text/css" media="screen" href="/css/layout.less"> ... <script type="text/javascript" src="/js/less-1.0.35.min.js"></script>
And the JS will generate just after its inclusion:
<style type="text/css" media="screen" id="less:css-layout"> /* THE COMPILED CODE */ </style>
In dev mode code is always compiled. In production you will get your styles if you previously compiled the css with the task we created. Why don’t automatically compile the CSS? Well, it would add complexity and I don’t want it. I’m idle, but I’m not so lazy as to not run the task to update .css files before uploading changes to my version control system.
That’s all! Comments are appreciated.
We have been working for a while with the django framework and we were also early adopters of the symfony framework using it almost from the begining in 2005. So I think I can write some of my thoughts about these two frameworks and try to make some comparisons between them. I’m not gonna try to make an exhaustive and data comparison, but only share my experience and impressions using both of them.
So, the first thing I should say is that both are gorgeous in many aspects. If you are a web developer and still don’t use any framework… man, what are you waiting for?
Documentation is also really good in both of them, and the learning curve, I think is more or less the same.
But all this said, my feeling is that actually django is better, and I’ll try to explain why in the next few lines.
- First, I think is usually easy to find where the things are. Maybe because you have less files in django that in symfony. In symfony many times you have too many folders and files, and it makes harder to find something.
- The way django manage forms and submissions is really good. The philosophy in symfony about forms is similar, but they are harder to manage, and usually you have to write so much code to make the things you want with forms.
- The templates in django is another pretty good feature. Especially the way you can “extend” the templates, the built-in tags and filters and so on. In symfony many times you have the feeling of writing more code when you are writing templates. Some people can see this as an advantage, but that’s not my case.
- The multiple ways you can do tests in python, especially using doctests is in my opinion another good point for django.
- And last, the python itself is like more “readable” and quick to write than php.
So, these are my impressions, as I said before these are only impressions, this is not an study about the frameworks. Anyway we continue working with symfony, especially in our open source project siwapp, first because is a really great framework, and secondly because it has many other advantages as well. And we hope the next release of symfony, symfony 2.0, will address many of these lacks and improve the framework in many ways.
Suppose we have HTML code with the following structure:
<body>
<a id="panel-previous" href="#">previous</a>
<ul id="panel">
<li>ad</li>
<li>adipisicing</li>
<li>aliqua</li>
<li>aliquip</li>
<li>amet</li>
<li style="display:none;">anim</li>
<li style="display:none;">aute</li>
<li style="display:none;">cillum</li>
<li style="display:none;">commodo</li>
<li style="display:none;">consectetur</li>
<li style="display:none;">consequat</li>
<li style="display:none;">culpa</li>
</ul>
<a id="panel-next" href="#">next</a>
</body>
We want to show only five items at once, and we want to show next and previous items in a scrolling-like manner. This approach is based on showing only those items that should remain visible and hiding the others. The other one would be the classical container vs. content divs.
You need jquery, jquery.timers plugin (included in the attachment zip file) and the code we are going to comment now, as a panel.cer.js file in the attachment.
(function($){
$.fn.cerPanel = function () {
var speed = arguments.length > 0 ? parseInt(arguments[0]) : 100;
return this.each(function(){
var panel = $(this);
$('#'+panel.attr('id')+'-next').mousedown(function(e){
$(this).everyTime(speed, 'next', function(i){
if (panel.children(':visible ~ :hidden').length > 0) {
panel.children(':visible + :hidden').show();
panel.children(':visible:first').hide();
}
});
}).mouseup(function(e){
$(this).stopTime('next');
}).click(function(e){ e.preventDefault(); });
$('#'+panel.attr('id')+'-previous').mousedown(function(e){
$(this).everyTime(speed, 'prev', function(i){
if (panel.children(':hidden ~ :visible').length > 0) {
panel.children(':hidden:not(:visible ~ :hidden):last').show();
panel.children(':visible:last').hide();
}
});
}).mouseup(function(e){
$(this).stopTime('prev');
}).click(function(e){ e.preventDefault(); });
});
};
})(jQuery);
After the document is loaded you can call:
$('#panel').cerPanel();
$('#panel').cerPanel(mySpeed);
You will notice that in our HTML we defined ‘panel-previous’ and ‘panel-next’ links. You can use any clickable tag.
Those links works similar; we will focus on the ‘next’ link first:
On mouse down a timer starts repeating the same action: if there are more hidden items after a visible one then show the first hidden after a visible item and hide the first visible item. On mouse up stop doing it.
The ‘previous’ link works looking for visible items after a hidden one. If one item matches the condition it shows “the last hidden item that is not located after a visible one” and hides the last visible item.
This is useful when we want to scroll “complete” block items inside a parent block; this is not recommended to scroll text in the usual way.
If you are a web developer, maybe this post title doesn’t say nothing new to you. But I’m really really tired of IE annoyances. Today I worked extra hours on an ajax problem with IE.
The page I was working on has an ajax call like this one:
<div id="LoginForm"> </div>
<script type="text/javascript">
new Ajax.Updater('LoginForm',
'/www.php/login/ajaxForm'),
{asynchronous:true, evalScripts:false, method:'get'})
</script>
Well, is the typical prototype ajax call. The call updates the “LoginForm” layer with the information of the user: if he is logged or not basically.
Everything works right on every browser. I remark: on every browser, except of course IE. Explorer has the bright idea of use always his cache to fill the layer, so when the user logout, and go to another page, the “ajax call” shows the cached content, and voilá: the user is logged in again!
Here the solution:
<div id="LoginForm"> </div>
<script type="text/javascript">
new Ajax.Updater('LoginForm',
'/www_dev.php/login/ajaxForm?rdm='+Math.floor(Math.random()*10000),
{asynchronous:true, evalScripts:false, method:'get'})
</script>
It’s pretty obvious knowing the problem, but anyway is ANOTHER annoyance!
Thank you Microsoft, for these great moments.
If you manage :focus CSS styles for certain input controls you may have noticed that Safari attempts against your pretty innovative design adding a blurry blue outline effect.
You can avoid this adding this:
input:focus {
outline-width:0;
...
}
And that’s all.


Recent Comments