9
9
* All the session and permission tables: they're just not needed.
10
10
* Enum: I don't know what this is or what it's for.
11
11
* NodeChange: Ditto.
12
-
13
- These models are far from perfect but are Good Enough(tm) to get some useful data out.
14
-
15
- One important mismatch between these models and the Trac database has to do with
16
- composite primary keys. Trac uses them for several tables, but Django does not support
17
- them yet (ticket #373).
18
-
19
- These are the tables that use them:
20
-
21
- * ticket_custom (model TicketCustom)
22
- * ticket_change (model TicketChange)
23
- * wiki (model Wiki)
24
- * attachment (model Attachment)
25
-
26
- To make these work with Django (for some definition of the word "work") we mark only
27
- one of their field as being the primary key (primary_key=True).
28
- This is obviously incorrect but — somewhat suprisingly — it doesn't break **everything**
29
- and the little that does actually work is good enough for what we're trying to do:
30
-
31
- * Model.objects.create(...) correctly creates the object in the db
32
- * Most queryset/manager methods work (in particular filter(), exclude(), all()
33
- and count())
34
-
35
- On the other hand, here's what absolutely DOES NOT work (the list is sadly not
36
- exhaustive):
37
-
38
- * Updating a model instance with save() will update ALL ROWS that happen to share
39
- the value for the field used as the "fake" primary key if they exist (resulting
40
- in a DBError)
41
- * The admin won't work (the "pk" field shortcut can't be used reliably since it can
42
- return multiple rows)
43
-
44
12
"""
45
13
46
14
from datetime import date
@@ -161,11 +129,11 @@ def __str__(self):
161
129
162
130
163
131
class TicketCustom (models .Model ):
132
+ pk = models .CompositePrimaryKey ("ticket" , "name" )
164
133
ticket = models .ForeignKey (
165
134
Ticket ,
166
135
related_name = "custom_fields" ,
167
136
db_column = "ticket" ,
168
- primary_key = True , # XXX See note at the top about composite pk
169
137
on_delete = models .DO_NOTHING ,
170
138
)
171
139
name = models .TextField ()
@@ -180,11 +148,11 @@ def __str__(self):
180
148
181
149
182
150
class TicketChange (models .Model ):
151
+ pk = models .CompositePrimaryKey ("ticket" , "_time" , "field" )
183
152
ticket = models .ForeignKey (
184
153
Ticket ,
185
154
related_name = "changes" ,
186
155
db_column = "ticket" ,
187
- primary_key = True , # XXX See note at the top about composite pk
188
156
on_delete = models .DO_NOTHING ,
189
157
)
190
158
author = models .TextField ()
@@ -292,9 +260,8 @@ def __str__(self):
292
260
293
261
294
262
class Wiki (models .Model ):
295
- name = models .TextField (
296
- primary_key = True
297
- ) # XXX See note at the top about composite pk
263
+ pk = models .CompositePrimaryKey ("name" , "version" )
264
+ name = models .TextField ()
298
265
version = models .IntegerField ()
299
266
_time = models .BigIntegerField (db_column = "time" )
300
267
time = time_property ("_time" )
@@ -312,10 +279,9 @@ def __str__(self):
312
279
313
280
314
281
class Attachment (models .Model ):
282
+ pk = models .CompositePrimaryKey ("type" , "id" , "filename" )
315
283
type = models .TextField ()
316
- id = models .TextField (
317
- primary_key = True
318
- ) # XXX See note at the top about composite pk
284
+ id = models .TextField ()
319
285
filename = models .TextField ()
320
286
size = models .IntegerField ()
321
287
_time = models .BigIntegerField (db_column = "time" )
0 commit comments