2009-05-28 13:46:09 +08:00
|
|
|
import os
|
|
|
|
import tempfile
|
2014-07-15 17:35:29 +08:00
|
|
|
import uuid
|
2008-03-20 14:56:23 +08:00
|
|
|
|
2015-01-28 20:35:27 +08:00
|
|
|
from django.contrib.contenttypes.fields import (
|
|
|
|
GenericForeignKey, GenericRelation,
|
|
|
|
)
|
2015-01-07 08:16:35 +08:00
|
|
|
from django.contrib.contenttypes.models import ContentType
|
2015-01-28 20:35:27 +08:00
|
|
|
from django.core.files.storage import FileSystemStorage
|
|
|
|
from django.db import models
|
|
|
|
from django.db.models.fields.files import ImageField, ImageFieldFile
|
2015-01-07 08:16:35 +08:00
|
|
|
from django.db.models.fields.related import (
|
2015-01-28 20:35:27 +08:00
|
|
|
ForeignKey, ForeignObject, ManyToManyField, OneToOneField,
|
2015-01-07 08:16:35 +08:00
|
|
|
)
|
2019-03-24 00:04:39 +08:00
|
|
|
from django.utils.translation import gettext_lazy as _
|
2009-05-28 13:46:09 +08:00
|
|
|
|
2015-01-28 20:35:27 +08:00
|
|
|
try:
|
|
|
|
from PIL import Image
|
|
|
|
except ImportError:
|
|
|
|
Image = None
|
|
|
|
|
2009-05-28 13:46:09 +08:00
|
|
|
|
2008-03-20 14:56:23 +08:00
|
|
|
class Foo(models.Model):
|
|
|
|
a = models.CharField(max_length=10)
|
2008-07-30 08:18:49 +08:00
|
|
|
d = models.DecimalField(max_digits=5, decimal_places=3)
|
2008-03-20 14:56:23 +08:00
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2008-03-20 14:56:23 +08:00
|
|
|
def get_foo():
|
2015-07-16 20:00:29 +08:00
|
|
|
return Foo.objects.get(id=1).pk
|
2008-03-20 14:56:23 +08:00
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2008-03-20 14:56:23 +08:00
|
|
|
class Bar(models.Model):
|
|
|
|
b = models.CharField(max_length=10)
|
2017-03-04 22:47:49 +08:00
|
|
|
a = models.ForeignKey(Foo, models.CASCADE, default=get_foo, related_name='bars')
|
2008-03-20 14:56:23 +08:00
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2008-07-27 15:22:39 +08:00
|
|
|
class Whiz(models.Model):
|
|
|
|
CHOICES = (
|
|
|
|
('Group 1', (
|
2013-10-20 07:33:10 +08:00
|
|
|
(1, 'First'),
|
|
|
|
(2, 'Second'),
|
2013-10-18 17:02:43 +08:00
|
|
|
)
|
2008-07-27 15:22:39 +08:00
|
|
|
),
|
|
|
|
('Group 2', (
|
2013-10-20 07:33:10 +08:00
|
|
|
(3, 'Third'),
|
|
|
|
(4, 'Fourth'),
|
2013-10-18 17:02:43 +08:00
|
|
|
)
|
2008-07-30 08:18:49 +08:00
|
|
|
),
|
2013-10-04 01:44:10 +08:00
|
|
|
(0, 'Other'),
|
2019-03-24 00:04:39 +08:00
|
|
|
(5, _('translated')),
|
2008-07-27 15:22:39 +08:00
|
|
|
)
|
|
|
|
c = models.IntegerField(choices=CHOICES, null=True)
|
2009-05-28 13:46:09 +08:00
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2019-01-05 04:03:53 +08:00
|
|
|
class WhizDelayed(models.Model):
|
|
|
|
c = models.IntegerField(choices=(), null=True)
|
|
|
|
|
|
|
|
|
|
|
|
# Contrived way of adding choices later.
|
|
|
|
WhizDelayed._meta.get_field('c').choices = Whiz.CHOICES
|
|
|
|
|
|
|
|
|
2014-07-28 05:39:40 +08:00
|
|
|
class WhizIter(models.Model):
|
2017-11-14 02:11:07 +08:00
|
|
|
c = models.IntegerField(choices=iter(Whiz.CHOICES), null=True)
|
2014-07-28 05:39:40 +08:00
|
|
|
|
|
|
|
|
|
|
|
class WhizIterEmpty(models.Model):
|
2017-11-14 02:11:07 +08:00
|
|
|
c = models.CharField(choices=iter(()), blank=True, max_length=1)
|
2014-07-28 05:39:40 +08:00
|
|
|
|
|
|
|
|
2019-01-05 04:03:53 +08:00
|
|
|
class Choiceful(models.Model):
|
|
|
|
no_choices = models.IntegerField(null=True)
|
|
|
|
empty_choices = models.IntegerField(choices=(), null=True)
|
|
|
|
with_choices = models.IntegerField(choices=[(1, 'A')], null=True)
|
|
|
|
empty_choices_bool = models.BooleanField(choices=())
|
|
|
|
empty_choices_text = models.TextField(choices=())
|
|
|
|
|
|
|
|
|
2008-11-12 08:35:24 +08:00
|
|
|
class BigD(models.Model):
|
2017-05-10 23:33:46 +08:00
|
|
|
d = models.DecimalField(max_digits=32, decimal_places=30)
|
2008-07-30 08:18:49 +08:00
|
|
|
|
2014-03-13 02:34:05 +08:00
|
|
|
|
2014-03-10 23:17:57 +08:00
|
|
|
class FloatModel(models.Model):
|
|
|
|
size = models.FloatField()
|
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2008-12-03 02:40:40 +08:00
|
|
|
class BigS(models.Model):
|
2009-05-28 13:46:09 +08:00
|
|
|
s = models.SlugField(max_length=255)
|
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2015-04-16 06:28:49 +08:00
|
|
|
class UnicodeSlugField(models.Model):
|
|
|
|
s = models.SlugField(max_length=255, allow_unicode=True)
|
|
|
|
|
|
|
|
|
2017-07-13 19:55:23 +08:00
|
|
|
class AutoModel(models.Model):
|
|
|
|
value = models.AutoField(primary_key=True)
|
|
|
|
|
|
|
|
|
|
|
|
class BigAutoModel(models.Model):
|
|
|
|
value = models.BigAutoField(primary_key=True)
|
|
|
|
|
|
|
|
|
|
|
|
class SmallAutoModel(models.Model):
|
|
|
|
value = models.SmallAutoField(primary_key=True)
|
|
|
|
|
|
|
|
|
2014-03-04 09:12:42 +08:00
|
|
|
class SmallIntegerModel(models.Model):
|
|
|
|
value = models.SmallIntegerField()
|
|
|
|
|
|
|
|
|
|
|
|
class IntegerModel(models.Model):
|
|
|
|
value = models.IntegerField()
|
|
|
|
|
|
|
|
|
|
|
|
class BigIntegerModel(models.Model):
|
2009-12-17 23:10:38 +08:00
|
|
|
value = models.BigIntegerField()
|
2013-10-04 01:44:10 +08:00
|
|
|
null_value = models.BigIntegerField(null=True, blank=True)
|
|
|
|
|
2009-05-28 13:46:09 +08:00
|
|
|
|
2014-03-04 09:12:42 +08:00
|
|
|
class PositiveSmallIntegerModel(models.Model):
|
|
|
|
value = models.PositiveSmallIntegerField()
|
|
|
|
|
|
|
|
|
|
|
|
class PositiveIntegerModel(models.Model):
|
|
|
|
value = models.PositiveIntegerField()
|
|
|
|
|
|
|
|
|
2010-01-10 06:05:10 +08:00
|
|
|
class Post(models.Model):
|
|
|
|
title = models.CharField(max_length=100)
|
|
|
|
body = models.TextField()
|
2010-03-10 15:42:25 +08:00
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2010-03-10 15:42:25 +08:00
|
|
|
class NullBooleanModel(models.Model):
|
2017-05-06 22:56:28 +08:00
|
|
|
nbfield = models.BooleanField(null=True, blank=True)
|
|
|
|
nbfield_old = models.NullBooleanField()
|
2010-03-10 15:42:25 +08:00
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2010-04-01 23:10:53 +08:00
|
|
|
class BooleanModel(models.Model):
|
2016-03-22 09:06:54 +08:00
|
|
|
bfield = models.BooleanField()
|
2010-04-09 20:39:08 +08:00
|
|
|
string = models.CharField(max_length=10, default='abc')
|
2010-03-10 15:42:25 +08:00
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2014-03-13 05:43:45 +08:00
|
|
|
class DateTimeModel(models.Model):
|
|
|
|
d = models.DateField()
|
|
|
|
dt = models.DateTimeField()
|
|
|
|
t = models.TimeField()
|
|
|
|
|
|
|
|
|
2014-07-24 20:57:24 +08:00
|
|
|
class DurationModel(models.Model):
|
|
|
|
field = models.DurationField()
|
|
|
|
|
|
|
|
|
2015-01-02 09:47:49 +08:00
|
|
|
class NullDurationModel(models.Model):
|
|
|
|
field = models.DurationField(null=True)
|
|
|
|
|
|
|
|
|
2013-09-30 03:56:04 +08:00
|
|
|
class PrimaryKeyCharModel(models.Model):
|
|
|
|
string = models.CharField(max_length=10, primary_key=True)
|
|
|
|
|
|
|
|
|
2012-10-26 07:25:59 +08:00
|
|
|
class FksToBooleans(models.Model):
|
2014-04-27 01:18:45 +08:00
|
|
|
"""Model with FKs to models with {Null,}BooleanField's, #15040"""
|
2015-07-22 22:43:21 +08:00
|
|
|
bf = models.ForeignKey(BooleanModel, models.CASCADE)
|
|
|
|
nbf = models.ForeignKey(NullBooleanModel, models.CASCADE)
|
2012-10-26 07:25:59 +08:00
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2013-09-30 03:56:04 +08:00
|
|
|
class FkToChar(models.Model):
|
|
|
|
"""Model with FK to a model with a CharField primary key, #19299"""
|
2015-07-22 22:43:21 +08:00
|
|
|
out = models.ForeignKey(PrimaryKeyCharModel, models.CASCADE)
|
2013-09-30 03:56:04 +08:00
|
|
|
|
|
|
|
|
2011-08-13 19:53:42 +08:00
|
|
|
class RenamedField(models.Model):
|
2013-10-04 01:44:10 +08:00
|
|
|
modelname = models.IntegerField(name="fieldname", choices=((1, 'One'),))
|
|
|
|
|
2011-08-13 19:53:42 +08:00
|
|
|
|
2012-09-02 00:32:27 +08:00
|
|
|
class VerboseNameField(models.Model):
|
|
|
|
id = models.AutoField("verbose pk", primary_key=True)
|
|
|
|
field1 = models.BigIntegerField("verbose field1")
|
2013-08-12 04:19:09 +08:00
|
|
|
field2 = models.BooleanField("verbose field2", default=False)
|
2012-09-02 00:32:27 +08:00
|
|
|
field3 = models.CharField("verbose field3", max_length=10)
|
2016-12-31 23:30:41 +08:00
|
|
|
field4 = models.DateField("verbose field4")
|
|
|
|
field5 = models.DateTimeField("verbose field5")
|
|
|
|
field6 = models.DecimalField("verbose field6", max_digits=6, decimal_places=1)
|
|
|
|
field7 = models.EmailField("verbose field7")
|
|
|
|
field8 = models.FileField("verbose field8", upload_to="unused")
|
|
|
|
field9 = models.FilePathField("verbose field9")
|
|
|
|
field10 = models.FloatField("verbose field10")
|
2014-03-21 22:54:53 +08:00
|
|
|
# Don't want to depend on Pillow in this test
|
2015-02-06 02:25:34 +08:00
|
|
|
# field_image = models.ImageField("verbose field")
|
2016-12-31 23:30:41 +08:00
|
|
|
field11 = models.IntegerField("verbose field11")
|
|
|
|
field12 = models.GenericIPAddressField("verbose field12", protocol="ipv4")
|
|
|
|
field13 = models.NullBooleanField("verbose field13")
|
|
|
|
field14 = models.PositiveIntegerField("verbose field14")
|
|
|
|
field15 = models.PositiveSmallIntegerField("verbose field15")
|
|
|
|
field16 = models.SlugField("verbose field16")
|
|
|
|
field17 = models.SmallIntegerField("verbose field17")
|
|
|
|
field18 = models.TextField("verbose field18")
|
|
|
|
field19 = models.TimeField("verbose field19")
|
|
|
|
field20 = models.URLField("verbose field20")
|
|
|
|
field21 = models.UUIDField("verbose field21")
|
|
|
|
field22 = models.DurationField("verbose field22")
|
2012-09-02 00:32:27 +08:00
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2015-01-05 18:32:25 +08:00
|
|
|
class GenericIPAddress(models.Model):
|
|
|
|
ip = models.GenericIPAddressField(null=True, protocol='ipv4')
|
|
|
|
|
|
|
|
|
2014-05-16 20:25:45 +08:00
|
|
|
###############################################################################
|
|
|
|
# These models aren't used in any test, just here to ensure they validate
|
|
|
|
# successfully.
|
|
|
|
|
2011-11-13 03:53:56 +08:00
|
|
|
# See ticket #16570.
|
|
|
|
class DecimalLessThanOne(models.Model):
|
|
|
|
d = models.DecimalField(max_digits=3, decimal_places=3)
|
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2014-05-16 20:25:45 +08:00
|
|
|
# See ticket #18389.
|
|
|
|
class FieldClassAttributeModel(models.Model):
|
|
|
|
field_class = models.CharField
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
|
2012-12-14 05:11:06 +08:00
|
|
|
class DataModel(models.Model):
|
|
|
|
short_data = models.BinaryField(max_length=10, default=b'\x08')
|
|
|
|
data = models.BinaryField()
|
|
|
|
|
2010-10-01 10:02:58 +08:00
|
|
|
###############################################################################
|
|
|
|
# FileField
|
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2010-10-01 10:02:58 +08:00
|
|
|
class Document(models.Model):
|
2016-09-21 05:31:23 +08:00
|
|
|
myfile = models.FileField(upload_to='unused', unique=True)
|
2010-10-01 10:02:58 +08:00
|
|
|
|
2016-11-13 01:11:23 +08:00
|
|
|
|
2009-05-28 13:46:09 +08:00
|
|
|
###############################################################################
|
|
|
|
# ImageField
|
|
|
|
|
2014-03-21 22:54:53 +08:00
|
|
|
# If Pillow available, do these tests.
|
2009-05-28 13:46:09 +08:00
|
|
|
if Image:
|
|
|
|
class TestImageFieldFile(ImageFieldFile):
|
|
|
|
"""
|
|
|
|
Custom Field File class that records whether or not the underlying file
|
|
|
|
was opened.
|
|
|
|
"""
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
self.was_opened = False
|
2017-01-21 21:13:44 +08:00
|
|
|
super().__init__(*args, **kwargs)
|
2013-10-04 01:44:10 +08:00
|
|
|
|
2009-05-28 13:46:09 +08:00
|
|
|
def open(self):
|
|
|
|
self.was_opened = True
|
2017-01-21 21:13:44 +08:00
|
|
|
super().open()
|
2009-05-28 13:46:09 +08:00
|
|
|
|
|
|
|
class TestImageField(ImageField):
|
|
|
|
attr_class = TestImageFieldFile
|
|
|
|
|
|
|
|
# Set up a temp directory for file storage.
|
2015-02-22 01:56:36 +08:00
|
|
|
temp_storage_dir = tempfile.mkdtemp()
|
2009-05-28 13:46:09 +08:00
|
|
|
temp_storage = FileSystemStorage(temp_storage_dir)
|
|
|
|
temp_upload_to_dir = os.path.join(temp_storage.location, 'tests')
|
|
|
|
|
|
|
|
class Person(models.Model):
|
|
|
|
"""
|
|
|
|
Model that defines an ImageField with no dimension fields.
|
|
|
|
"""
|
|
|
|
name = models.CharField(max_length=50)
|
|
|
|
mugshot = TestImageField(storage=temp_storage, upload_to='tests')
|
|
|
|
|
2015-12-03 07:55:50 +08:00
|
|
|
class AbstractPersonWithHeight(models.Model):
|
2009-05-28 13:46:09 +08:00
|
|
|
"""
|
2013-10-04 01:44:10 +08:00
|
|
|
Abstract model that defines an ImageField with only one dimension field
|
|
|
|
to make sure the dimension update is correctly run on concrete subclass
|
|
|
|
instance post-initialization.
|
2009-05-28 13:46:09 +08:00
|
|
|
"""
|
|
|
|
mugshot = TestImageField(storage=temp_storage, upload_to='tests',
|
|
|
|
height_field='mugshot_height')
|
|
|
|
mugshot_height = models.PositiveSmallIntegerField()
|
|
|
|
|
2013-10-04 01:44:10 +08:00
|
|
|
class Meta:
|
|
|
|
abstract = True
|
|
|
|
|
2015-12-03 07:55:50 +08:00
|
|
|
class PersonWithHeight(AbstractPersonWithHeight):
|
2013-10-04 01:44:10 +08:00
|
|
|
"""
|
2015-12-03 07:55:50 +08:00
|
|
|
Concrete model that subclass an abstract one with only on dimension
|
2013-10-04 01:44:10 +08:00
|
|
|
field.
|
|
|
|
"""
|
|
|
|
name = models.CharField(max_length=50)
|
|
|
|
|
2009-05-28 13:46:09 +08:00
|
|
|
class PersonWithHeightAndWidth(models.Model):
|
|
|
|
"""
|
|
|
|
Model that defines height and width fields after the ImageField.
|
|
|
|
"""
|
|
|
|
name = models.CharField(max_length=50)
|
|
|
|
mugshot = TestImageField(storage=temp_storage, upload_to='tests',
|
|
|
|
height_field='mugshot_height',
|
|
|
|
width_field='mugshot_width')
|
|
|
|
mugshot_height = models.PositiveSmallIntegerField()
|
|
|
|
mugshot_width = models.PositiveSmallIntegerField()
|
|
|
|
|
|
|
|
class PersonDimensionsFirst(models.Model):
|
|
|
|
"""
|
|
|
|
Model that defines height and width fields before the ImageField.
|
|
|
|
"""
|
|
|
|
name = models.CharField(max_length=50)
|
|
|
|
mugshot_height = models.PositiveSmallIntegerField()
|
|
|
|
mugshot_width = models.PositiveSmallIntegerField()
|
|
|
|
mugshot = TestImageField(storage=temp_storage, upload_to='tests',
|
|
|
|
height_field='mugshot_height',
|
|
|
|
width_field='mugshot_width')
|
|
|
|
|
|
|
|
class PersonTwoImages(models.Model):
|
|
|
|
"""
|
|
|
|
Model that:
|
|
|
|
* Defines two ImageFields
|
|
|
|
* Defines the height/width fields before the ImageFields
|
2015-12-03 07:55:50 +08:00
|
|
|
* Has a nullable ImageField
|
2009-05-28 13:46:09 +08:00
|
|
|
"""
|
|
|
|
name = models.CharField(max_length=50)
|
|
|
|
mugshot_height = models.PositiveSmallIntegerField()
|
|
|
|
mugshot_width = models.PositiveSmallIntegerField()
|
|
|
|
mugshot = TestImageField(storage=temp_storage, upload_to='tests',
|
|
|
|
height_field='mugshot_height',
|
|
|
|
width_field='mugshot_width')
|
|
|
|
headshot_height = models.PositiveSmallIntegerField(
|
2013-10-20 07:33:10 +08:00
|
|
|
blank=True, null=True)
|
2009-05-28 13:46:09 +08:00
|
|
|
headshot_width = models.PositiveSmallIntegerField(
|
2013-10-20 07:33:10 +08:00
|
|
|
blank=True, null=True)
|
2009-05-28 13:46:09 +08:00
|
|
|
headshot = TestImageField(blank=True, null=True,
|
|
|
|
storage=temp_storage, upload_to='tests',
|
|
|
|
height_field='headshot_height',
|
|
|
|
width_field='headshot_width')
|
|
|
|
|
2015-01-07 08:16:35 +08:00
|
|
|
|
|
|
|
class AllFieldsModel(models.Model):
|
|
|
|
big_integer = models.BigIntegerField()
|
|
|
|
binary = models.BinaryField()
|
|
|
|
boolean = models.BooleanField(default=False)
|
|
|
|
char = models.CharField(max_length=10)
|
|
|
|
date = models.DateField()
|
|
|
|
datetime = models.DateTimeField()
|
|
|
|
decimal = models.DecimalField(decimal_places=2, max_digits=2)
|
|
|
|
duration = models.DurationField()
|
|
|
|
email = models.EmailField()
|
|
|
|
file_path = models.FilePathField()
|
|
|
|
floatf = models.FloatField()
|
|
|
|
integer = models.IntegerField()
|
|
|
|
generic_ip = models.GenericIPAddressField()
|
|
|
|
null_boolean = models.NullBooleanField()
|
|
|
|
positive_integer = models.PositiveIntegerField()
|
|
|
|
positive_small_integer = models.PositiveSmallIntegerField()
|
|
|
|
slug = models.SlugField()
|
|
|
|
small_integer = models.SmallIntegerField()
|
|
|
|
text = models.TextField()
|
|
|
|
time = models.TimeField()
|
|
|
|
url = models.URLField()
|
|
|
|
uuid = models.UUIDField()
|
|
|
|
|
|
|
|
fo = ForeignObject(
|
|
|
|
'self',
|
2015-07-22 22:43:21 +08:00
|
|
|
on_delete=models.CASCADE,
|
2019-02-19 14:32:33 +08:00
|
|
|
from_fields=['positive_integer'],
|
2015-01-07 08:16:35 +08:00
|
|
|
to_fields=['id'],
|
|
|
|
related_name='reverse'
|
|
|
|
)
|
|
|
|
fk = ForeignKey(
|
|
|
|
'self',
|
2015-07-22 22:43:21 +08:00
|
|
|
models.CASCADE,
|
2015-01-07 08:16:35 +08:00
|
|
|
related_name='reverse2'
|
|
|
|
)
|
|
|
|
m2m = ManyToManyField('self')
|
2015-07-22 22:43:21 +08:00
|
|
|
oto = OneToOneField('self', models.CASCADE)
|
2015-01-07 08:16:35 +08:00
|
|
|
|
|
|
|
object_id = models.PositiveIntegerField()
|
2015-07-22 22:43:21 +08:00
|
|
|
content_type = models.ForeignKey(ContentType, models.CASCADE)
|
2015-01-07 08:16:35 +08:00
|
|
|
gfk = GenericForeignKey()
|
|
|
|
gr = GenericRelation(DataModel)
|
|
|
|
|
|
|
|
|
2017-08-31 21:34:44 +08:00
|
|
|
class ManyToMany(models.Model):
|
|
|
|
m2m = models.ManyToManyField('self')
|
|
|
|
|
|
|
|
|
2009-05-28 13:46:09 +08:00
|
|
|
###############################################################################
|
2014-07-15 17:35:29 +08:00
|
|
|
|
|
|
|
|
|
|
|
class UUIDModel(models.Model):
|
|
|
|
field = models.UUIDField()
|
|
|
|
|
|
|
|
|
|
|
|
class NullableUUIDModel(models.Model):
|
|
|
|
field = models.UUIDField(blank=True, null=True)
|
|
|
|
|
|
|
|
|
|
|
|
class PrimaryKeyUUIDModel(models.Model):
|
|
|
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
|
2015-02-12 14:28:24 +08:00
|
|
|
|
|
|
|
|
2015-02-15 03:37:12 +08:00
|
|
|
class RelatedToUUIDModel(models.Model):
|
2015-07-22 22:43:21 +08:00
|
|
|
uuid_fk = models.ForeignKey('PrimaryKeyUUIDModel', models.CASCADE)
|
2015-05-13 05:04:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
class UUIDChild(PrimaryKeyUUIDModel):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class UUIDGrandchild(UUIDChild):
|
|
|
|
pass
|