Django documentation

14. Using a custom primary key

This example describes Django version 0.95. For the current example, go here.

By default, Django adds an "id" field to each model. But you can override this behavior by explicitly adding primary_key=True to a field.

Model source code

from django.db import models

class Employee(models.Model):
    employee_code = models.CharField(maxlength=10, primary_key=True,
            db_column = 'code')
    first_name = models.CharField(maxlength=20)
    last_name = models.CharField(maxlength=20)
    class Meta:
        ordering = ('last_name', 'first_name')

    def __str__(self):
        return "%s %s" % (self.first_name, self.last_name)

class Business(models.Model):
    name = models.CharField(maxlength=20, primary_key=True)
    employees = models.ManyToManyField(Employee)
    class Meta:
        verbose_name_plural = 'businesses'

    def __str__(self):
        return self.name

API_TESTS = """
>>> dan = Employee(employee_code='ABC123', first_name='Dan', last_name='Jones')
>>> dan.save()
>>> Employee.objects.all()
[<Employee: Dan Jones>]

>>> fran = Employee(employee_code='XYZ456', first_name='Fran', last_name='Bones')
>>> fran.save()
>>> Employee.objects.all()
[<Employee: Fran Bones>, <Employee: Dan Jones>]

>>> Employee.objects.get(pk='ABC123')
<Employee: Dan Jones>
>>> Employee.objects.get(pk='XYZ456')
<Employee: Fran Bones>
>>> Employee.objects.get(pk='foo')
Traceback (most recent call last):
    ...
DoesNotExist: Employee matching query does not exist.

# Use the name of the primary key, rather than pk.
>>> Employee.objects.get(employee_code__exact='ABC123')
<Employee: Dan Jones>

# Fran got married and changed her last name.
>>> fran = Employee.objects.get(pk='XYZ456')
>>> fran.last_name = 'Jones'
>>> fran.save()
>>> Employee.objects.filter(last_name__exact='Jones')
[<Employee: Dan Jones>, <Employee: Fran Jones>]
>>> Employee.objects.in_bulk(['ABC123', 'XYZ456'])
{'XYZ456': <Employee: Fran Jones>, 'ABC123': <Employee: Dan Jones>}

>>> b = Business(name='Sears')
>>> b.save()
>>> b.employees.add(dan, fran)
>>> b.employees.all()
[<Employee: Dan Jones>, <Employee: Fran Jones>]
>>> fran.business_set.all()
[<Business: Sears>]
>>> Business.objects.in_bulk(['Sears'])
{'Sears': <Business: Sears>}

>>> Business.objects.filter(name__exact='Sears')
[<Business: Sears>]
>>> Business.objects.filter(pk='Sears')
[<Business: Sears>]

# Queries across tables, involving primary key
>>> Employee.objects.filter(business__name__exact='Sears')
[<Employee: Dan Jones>, <Employee: Fran Jones>]
>>> Employee.objects.filter(business__pk='Sears')
[<Employee: Dan Jones>, <Employee: Fran Jones>]

>>> Business.objects.filter(employees__employee_code__exact='ABC123')
[<Business: Sears>]
>>> Business.objects.filter(employees__pk='ABC123')
[<Business: Sears>]
>>> Business.objects.filter(employees__first_name__startswith='Fran')
[<Business: Sears>]

"""