models.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. """
  2. Various complex queries that have been problematic in the past.
  3. """
  4. from __future__ import unicode_literals
  5. import threading
  6. from django.db import models
  7. from django.utils import six
  8. from django.utils.encoding import python_2_unicode_compatible
  9. class DumbCategory(models.Model):
  10. pass
  11. class ProxyCategory(DumbCategory):
  12. class Meta:
  13. proxy = True
  14. class NamedCategory(DumbCategory):
  15. name = models.CharField(max_length=10)
  16. @python_2_unicode_compatible
  17. class Tag(models.Model):
  18. name = models.CharField(max_length=10)
  19. parent = models.ForeignKey('self', blank=True, null=True,
  20. related_name='children')
  21. category = models.ForeignKey(NamedCategory, null=True, default=None)
  22. class Meta:
  23. ordering = ['name']
  24. def __str__(self):
  25. return self.name
  26. @python_2_unicode_compatible
  27. class Note(models.Model):
  28. note = models.CharField(max_length=100)
  29. misc = models.CharField(max_length=10)
  30. class Meta:
  31. ordering = ['note']
  32. def __str__(self):
  33. return self.note
  34. def __init__(self, *args, **kwargs):
  35. super(Note, self).__init__(*args, **kwargs)
  36. # Regression for #13227 -- having an attribute that
  37. # is unpickleable doesn't stop you from cloning queries
  38. # that use objects of that type as an argument.
  39. self.lock = threading.Lock()
  40. @python_2_unicode_compatible
  41. class Annotation(models.Model):
  42. name = models.CharField(max_length=10)
  43. tag = models.ForeignKey(Tag)
  44. notes = models.ManyToManyField(Note)
  45. def __str__(self):
  46. return self.name
  47. @python_2_unicode_compatible
  48. class ExtraInfo(models.Model):
  49. info = models.CharField(max_length=100)
  50. note = models.ForeignKey(Note)
  51. value = models.IntegerField(null=True)
  52. class Meta:
  53. ordering = ['info']
  54. def __str__(self):
  55. return self.info
  56. @python_2_unicode_compatible
  57. class Author(models.Model):
  58. name = models.CharField(max_length=10)
  59. num = models.IntegerField(unique=True)
  60. extra = models.ForeignKey(ExtraInfo)
  61. class Meta:
  62. ordering = ['name']
  63. def __str__(self):
  64. return self.name
  65. @python_2_unicode_compatible
  66. class Item(models.Model):
  67. name = models.CharField(max_length=10)
  68. created = models.DateTimeField()
  69. modified = models.DateTimeField(blank=True, null=True)
  70. tags = models.ManyToManyField(Tag, blank=True, null=True)
  71. creator = models.ForeignKey(Author)
  72. note = models.ForeignKey(Note)
  73. class Meta:
  74. ordering = ['-note', 'name']
  75. def __str__(self):
  76. return self.name
  77. @python_2_unicode_compatible
  78. class Report(models.Model):
  79. name = models.CharField(max_length=10)
  80. creator = models.ForeignKey(Author, to_field='num', null=True)
  81. def __str__(self):
  82. return self.name
  83. @python_2_unicode_compatible
  84. class Ranking(models.Model):
  85. rank = models.IntegerField()
  86. author = models.ForeignKey(Author)
  87. class Meta:
  88. # A complex ordering specification. Should stress the system a bit.
  89. ordering = ('author__extra__note', 'author__name', 'rank')
  90. def __str__(self):
  91. return '%d: %s' % (self.rank, self.author.name)
  92. @python_2_unicode_compatible
  93. class Cover(models.Model):
  94. title = models.CharField(max_length=50)
  95. item = models.ForeignKey(Item)
  96. class Meta:
  97. ordering = ['item']
  98. def __str__(self):
  99. return self.title
  100. @python_2_unicode_compatible
  101. class Number(models.Model):
  102. num = models.IntegerField()
  103. def __str__(self):
  104. return six.text_type(self.num)
  105. # Symmetrical m2m field with a normal field using the reverse accesor name
  106. # ("valid").
  107. class Valid(models.Model):
  108. valid = models.CharField(max_length=10)
  109. parent = models.ManyToManyField('self')
  110. class Meta:
  111. ordering = ['valid']
  112. # Some funky cross-linked models for testing a couple of infinite recursion
  113. # cases.
  114. class X(models.Model):
  115. y = models.ForeignKey('Y')
  116. class Y(models.Model):
  117. x1 = models.ForeignKey(X, related_name='y1')
  118. # Some models with a cycle in the default ordering. This would be bad if we
  119. # didn't catch the infinite loop.
  120. class LoopX(models.Model):
  121. y = models.ForeignKey('LoopY')
  122. class Meta:
  123. ordering = ['y']
  124. class LoopY(models.Model):
  125. x = models.ForeignKey(LoopX)
  126. class Meta:
  127. ordering = ['x']
  128. class LoopZ(models.Model):
  129. z = models.ForeignKey('self')
  130. class Meta:
  131. ordering = ['z']
  132. # A model and custom default manager combination.
  133. class CustomManager(models.Manager):
  134. def get_queryset(self):
  135. qs = super(CustomManager, self).get_queryset()
  136. return qs.filter(public=True, tag__name='t1')
  137. @python_2_unicode_compatible
  138. class ManagedModel(models.Model):
  139. data = models.CharField(max_length=10)
  140. tag = models.ForeignKey(Tag)
  141. public = models.BooleanField(default=True)
  142. objects = CustomManager()
  143. normal_manager = models.Manager()
  144. def __str__(self):
  145. return self.data
  146. # An inter-related setup with multiple paths from Child to Detail.
  147. class Detail(models.Model):
  148. data = models.CharField(max_length=10)
  149. class MemberManager(models.Manager):
  150. def get_queryset(self):
  151. return super(MemberManager, self).get_queryset().select_related("details")
  152. class Member(models.Model):
  153. name = models.CharField(max_length=10)
  154. details = models.OneToOneField(Detail, primary_key=True)
  155. objects = MemberManager()
  156. class Child(models.Model):
  157. person = models.OneToOneField(Member, primary_key=True)
  158. parent = models.ForeignKey(Member, related_name="children")
  159. # Custom primary keys interfered with ordering in the past.
  160. class CustomPk(models.Model):
  161. name = models.CharField(max_length=10, primary_key=True)
  162. extra = models.CharField(max_length=10)
  163. class Meta:
  164. ordering = ['name', 'extra']
  165. class Related(models.Model):
  166. custom = models.ForeignKey(CustomPk)
  167. # An inter-related setup with a model subclass that has a nullable
  168. # path to another model, and a return path from that model.
  169. @python_2_unicode_compatible
  170. class Celebrity(models.Model):
  171. name = models.CharField("Name", max_length=20)
  172. greatest_fan = models.ForeignKey("Fan", null=True, unique=True)
  173. def __str__(self):
  174. return self.name
  175. class TvChef(Celebrity):
  176. pass
  177. class Fan(models.Model):
  178. fan_of = models.ForeignKey(Celebrity)
  179. # Multiple foreign keys
  180. @python_2_unicode_compatible
  181. class LeafA(models.Model):
  182. data = models.CharField(max_length=10)
  183. def __str__(self):
  184. return self.data
  185. class LeafB(models.Model):
  186. data = models.CharField(max_length=10)
  187. class Join(models.Model):
  188. a = models.ForeignKey(LeafA)
  189. b = models.ForeignKey(LeafB)
  190. @python_2_unicode_compatible
  191. class ReservedName(models.Model):
  192. name = models.CharField(max_length=20)
  193. order = models.IntegerField()
  194. def __str__(self):
  195. return self.name
  196. # A simpler shared-foreign-key setup that can expose some problems.
  197. @python_2_unicode_compatible
  198. class SharedConnection(models.Model):
  199. data = models.CharField(max_length=10)
  200. def __str__(self):
  201. return self.data
  202. class PointerA(models.Model):
  203. connection = models.ForeignKey(SharedConnection)
  204. class PointerB(models.Model):
  205. connection = models.ForeignKey(SharedConnection)
  206. # Multi-layer ordering
  207. @python_2_unicode_compatible
  208. class SingleObject(models.Model):
  209. name = models.CharField(max_length=10)
  210. class Meta:
  211. ordering = ['name']
  212. def __str__(self):
  213. return self.name
  214. class RelatedObject(models.Model):
  215. single = models.ForeignKey(SingleObject, null=True)
  216. f = models.IntegerField(null=True)
  217. class Meta:
  218. ordering = ['single']
  219. @python_2_unicode_compatible
  220. class Plaything(models.Model):
  221. name = models.CharField(max_length=10)
  222. others = models.ForeignKey(RelatedObject, null=True)
  223. class Meta:
  224. ordering = ['others']
  225. def __str__(self):
  226. return self.name
  227. class Article(models.Model):
  228. name = models.CharField(max_length=20)
  229. created = models.DateTimeField()
  230. @python_2_unicode_compatible
  231. class Food(models.Model):
  232. name = models.CharField(max_length=20, unique=True)
  233. def __str__(self):
  234. return self.name
  235. @python_2_unicode_compatible
  236. class Eaten(models.Model):
  237. food = models.ForeignKey(Food, to_field="name", null=True)
  238. meal = models.CharField(max_length=20)
  239. def __str__(self):
  240. return "%s at %s" % (self.food, self.meal)
  241. @python_2_unicode_compatible
  242. class Node(models.Model):
  243. num = models.IntegerField(unique=True)
  244. parent = models.ForeignKey("self", to_field="num", null=True)
  245. def __str__(self):
  246. return "%s" % self.num
  247. # Bug #12252
  248. @python_2_unicode_compatible
  249. class ObjectA(models.Model):
  250. name = models.CharField(max_length=50)
  251. def __str__(self):
  252. return self.name
  253. @python_2_unicode_compatible
  254. class ObjectB(models.Model):
  255. name = models.CharField(max_length=50)
  256. objecta = models.ForeignKey(ObjectA)
  257. num = models.PositiveSmallIntegerField()
  258. def __str__(self):
  259. return self.name
  260. @python_2_unicode_compatible
  261. class ObjectC(models.Model):
  262. name = models.CharField(max_length=50)
  263. objecta = models.ForeignKey(ObjectA)
  264. objectb = models.ForeignKey(ObjectB)
  265. def __str__(self):
  266. return self.name
  267. @python_2_unicode_compatible
  268. class SimpleCategory(models.Model):
  269. name = models.CharField(max_length=15)
  270. def __str__(self):
  271. return self.name
  272. @python_2_unicode_compatible
  273. class SpecialCategory(SimpleCategory):
  274. special_name = models.CharField(max_length=15)
  275. def __str__(self):
  276. return self.name + " " + self.special_name
  277. @python_2_unicode_compatible
  278. class CategoryItem(models.Model):
  279. category = models.ForeignKey(SimpleCategory)
  280. def __str__(self):
  281. return "category item: " + str(self.category)
  282. @python_2_unicode_compatible
  283. class OneToOneCategory(models.Model):
  284. new_name = models.CharField(max_length=15)
  285. category = models.OneToOneField(SimpleCategory)
  286. def __str__(self):
  287. return "one2one " + self.new_name
  288. class NullableName(models.Model):
  289. name = models.CharField(max_length=20, null=True)
  290. class Meta:
  291. ordering = ['id']
  292. class ModelD(models.Model):
  293. name = models.TextField()
  294. class ModelC(models.Model):
  295. name = models.TextField()
  296. class ModelB(models.Model):
  297. name = models.TextField()
  298. c = models.ForeignKey(ModelC)
  299. class ModelA(models.Model):
  300. name = models.TextField()
  301. b = models.ForeignKey(ModelB, null=True)
  302. d = models.ForeignKey(ModelD)
  303. @python_2_unicode_compatible
  304. class Job(models.Model):
  305. name = models.CharField(max_length=20, unique=True)
  306. def __str__(self):
  307. return self.name
  308. class JobResponsibilities(models.Model):
  309. job = models.ForeignKey(Job, to_field='name')
  310. responsibility = models.ForeignKey('Responsibility', to_field='description')
  311. @python_2_unicode_compatible
  312. class Responsibility(models.Model):
  313. description = models.CharField(max_length=20, unique=True)
  314. jobs = models.ManyToManyField(Job, through=JobResponsibilities,
  315. related_name='responsibilities')
  316. def __str__(self):
  317. return self.description
  318. # Models for disjunction join promotion low level testing.
  319. class FK1(models.Model):
  320. f1 = models.TextField()
  321. f2 = models.TextField()
  322. class FK2(models.Model):
  323. f1 = models.TextField()
  324. f2 = models.TextField()
  325. class FK3(models.Model):
  326. f1 = models.TextField()
  327. f2 = models.TextField()
  328. class BaseA(models.Model):
  329. a = models.ForeignKey(FK1, null=True)
  330. b = models.ForeignKey(FK2, null=True)
  331. c = models.ForeignKey(FK3, null=True)
  332. @python_2_unicode_compatible
  333. class Identifier(models.Model):
  334. name = models.CharField(max_length=100)
  335. def __str__(self):
  336. return self.name
  337. class Program(models.Model):
  338. identifier = models.OneToOneField(Identifier)
  339. class Channel(models.Model):
  340. programs = models.ManyToManyField(Program)
  341. identifier = models.OneToOneField(Identifier)
  342. class Book(models.Model):
  343. title = models.TextField()
  344. chapter = models.ForeignKey('Chapter')
  345. class Chapter(models.Model):
  346. title = models.TextField()
  347. paragraph = models.ForeignKey('Paragraph')
  348. class Paragraph(models.Model):
  349. text = models.TextField()
  350. page = models.ManyToManyField('Page')
  351. class Page(models.Model):
  352. text = models.TextField()
  353. class MyObject(models.Model):
  354. parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
  355. data = models.CharField(max_length=100)
  356. created_at = models.DateTimeField(auto_now_add=True)
  357. # Models for #17600 regressions
  358. @python_2_unicode_compatible
  359. class Order(models.Model):
  360. id = models.IntegerField(primary_key=True)
  361. class Meta:
  362. ordering = ('pk', )
  363. def __str__(self):
  364. return '%s' % self.pk
  365. @python_2_unicode_compatible
  366. class OrderItem(models.Model):
  367. order = models.ForeignKey(Order, related_name='items')
  368. status = models.IntegerField()
  369. class Meta:
  370. ordering = ('pk', )
  371. def __str__(self):
  372. return '%s' % self.pk
  373. class BaseUser(models.Model):
  374. pass
  375. @python_2_unicode_compatible
  376. class Task(models.Model):
  377. title = models.CharField(max_length=10)
  378. owner = models.ForeignKey(BaseUser, related_name='owner')
  379. creator = models.ForeignKey(BaseUser, related_name='creator')
  380. def __str__(self):
  381. return self.title
  382. @python_2_unicode_compatible
  383. class Staff(models.Model):
  384. name = models.CharField(max_length=10)
  385. def __str__(self):
  386. return self.name
  387. @python_2_unicode_compatible
  388. class StaffUser(BaseUser):
  389. staff = models.OneToOneField(Staff, related_name='user')
  390. def __str__(self):
  391. return self.staff