| 1 |
""" |
|---|
| 2 |
>>> rm = RevisionableModel.objects.create(title='First Revision') |
|---|
| 3 |
>>> rm.pk, rm.base.pk |
|---|
| 4 |
(1, 1) |
|---|
| 5 |
|
|---|
| 6 |
>>> rm2 = rm.new_revision() |
|---|
| 7 |
>>> rm2.title = "Second Revision" |
|---|
| 8 |
>>> rm2.save() |
|---|
| 9 |
>>> print u"%s of %s" % (rm2.title, rm2.base.title) |
|---|
| 10 |
Second Revision of First Revision |
|---|
| 11 |
|
|---|
| 12 |
>>> rm2.pk, rm2.base.pk |
|---|
| 13 |
(2, 1) |
|---|
| 14 |
|
|---|
| 15 |
Queryset to match most recent revision: |
|---|
| 16 |
>>> qs = RevisionableModel.objects.extra(where=["%(table)s.id IN (SELECT MAX(rev.id) FROM %(table)s AS rev GROUP BY rev.base_id)" % {'table': RevisionableModel._meta.db_table,}],) |
|---|
| 17 |
>>> qs |
|---|
| 18 |
[<RevisionableModel: Second Revision (2, 1)>] |
|---|
| 19 |
|
|---|
| 20 |
Queryset to search for string in title: |
|---|
| 21 |
>>> qs2 = RevisionableModel.objects.filter(title__contains="Revision") |
|---|
| 22 |
>>> qs2 |
|---|
| 23 |
[<RevisionableModel: First Revision (1, 1)>, <RevisionableModel: Second Revision (2, 1)>] |
|---|
| 24 |
|
|---|
| 25 |
Following queryset should return the most recent revision (fails as of r7544): |
|---|
| 26 |
>>> qs & qs2 |
|---|
| 27 |
[<RevisionableModel: Second Revision (2, 1)>] |
|---|
| 28 |
|
|---|
| 29 |
This is what we would expect: |
|---|
| 30 |
>>> qs.filter(title__contains="Revision") |
|---|
| 31 |
[<RevisionableModel: Second Revision (2, 1)>] |
|---|
| 32 |
""" |
|---|
| 33 |
|
|---|
| 34 |
import copy |
|---|
| 35 |
|
|---|
| 36 |
from django.db import models |
|---|
| 37 |
from django.db.models.query import Q |
|---|
| 38 |
|
|---|
| 39 |
|
|---|
| 40 |
class RevisionableModel(models.Model): |
|---|
| 41 |
base = models.ForeignKey('self', null=True) |
|---|
| 42 |
title = models.CharField(blank=True, max_length=255) |
|---|
| 43 |
|
|---|
| 44 |
def __unicode__(self): |
|---|
| 45 |
return u"%s (%s, %s)" % (self.title, self.id, self.base.id) |
|---|
| 46 |
|
|---|
| 47 |
def save(self): |
|---|
| 48 |
super(RevisionableModel, self).save() |
|---|
| 49 |
if not self.base: |
|---|
| 50 |
self.base = self |
|---|
| 51 |
super(RevisionableModel, self).save() |
|---|
| 52 |
|
|---|
| 53 |
def new_revision(self): |
|---|
| 54 |
new_revision = copy.copy(self) |
|---|
| 55 |
new_revision.pk = None |
|---|
| 56 |
return new_revision |
|---|