models.py 17 KB

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