As for a mature web framework django's ORM generates automatic integer primary keys if none are present. This feature is cool, cause we are relieved from generating our own primary keys (if its problematic), but we loose some easily accessible semantic information - for example: a car's primary key may be it's registration number instead of a meaningless integer. Whats more, a primary key is used in the default object __eq__ / __cmp__ functions, which makes it easier to filter data (no need for subselects).
But let's look at this situation:
class Dude(models.Model):
name = models.CharField(primary_key=True, max_length=100)
#and so on
We have a 'Dude' that should have a unique name, primary keys are in general unique so there's no problem here. Suppose we have some form where you add 'dudes'. So we execute:
try:
Dude(name='John', **some_fields).save()
#some more code
Dude(name='John', **some_other_fields).save()
print "You don\'t expect to see this message"
except IntegrityError as ie:
pass
The logic states, that if you try to create another entry with a same value of a unique field, django should raise an integrity error. Well it will not, because this is also a primary key, if a 'dude' with a specific name exists, django interprets it like this:
Dude.objects.filter(name='John').update(**some_other_fields)
For me this was a bit unintuitive, but when think about it - this approach makes sense. All in all, I would recommend using a custom primary_key field only if there is some semantic/logical background behind it.
~KR