~ubuntu-branches/ubuntu/quantal/python-django/quantal

« back to all changes in this revision

Viewing changes to tests/regressiontests/admin_views/models.py

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2009-07-29 11:26:28 UTC
  • mfrom: (1.1.8 upstream) (4.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20090729112628-pg09ino8sz0sj21t
Tags: 1.1-1
* New upstream release.
* Merge from experimental:
  - Ship FastCGI initscript and /etc/default file in python-django's examples
    directory (Closes: #538863)
  - Drop "05_10539-sphinx06-compatibility.diff"; it has been applied
    upstream.
  - Bump Standards-Version to 3.8.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
import tempfile
 
3
import os
 
4
from django.core.files.storage import FileSystemStorage
 
5
from django.db import models
 
6
from django.contrib import admin
 
7
from django.core.mail import EmailMessage
 
8
 
 
9
class Section(models.Model):
 
10
    """
 
11
    A simple section that links to articles, to test linking to related items
 
12
    in admin views.
 
13
    """
 
14
    name = models.CharField(max_length=100)
 
15
 
 
16
class Article(models.Model):
 
17
    """
 
18
    A simple article to test admin views. Test backwards compatibility.
 
19
    """
 
20
    title = models.CharField(max_length=100)
 
21
    content = models.TextField()
 
22
    date = models.DateTimeField()
 
23
    section = models.ForeignKey(Section)
 
24
 
 
25
    def __unicode__(self):
 
26
        return self.title
 
27
 
 
28
    def model_year(self):
 
29
        return self.date.year
 
30
    model_year.admin_order_field = 'date'
 
31
 
 
32
class Book(models.Model):
 
33
    """
 
34
    A simple book that has chapters.
 
35
    """
 
36
    name = models.CharField(max_length=100, verbose_name=u'¿Name?')
 
37
 
 
38
    def __unicode__(self):
 
39
        return self.name
 
40
 
 
41
class Promo(models.Model):
 
42
    name = models.CharField(max_length=100, verbose_name=u'¿Name?')
 
43
    book = models.ForeignKey(Book)
 
44
 
 
45
    def __unicode__(self):
 
46
        return self.name
 
47
 
 
48
class Chapter(models.Model):
 
49
    title = models.CharField(max_length=100, verbose_name=u'¿Title?')
 
50
    content = models.TextField()
 
51
    book = models.ForeignKey(Book)
 
52
 
 
53
    def __unicode__(self):
 
54
        return self.title
 
55
 
 
56
    class Meta:
 
57
        verbose_name = u'¿Chapter?'
 
58
 
 
59
class ChapterXtra1(models.Model):
 
60
    chap = models.OneToOneField(Chapter, verbose_name=u'¿Chap?')
 
61
    xtra = models.CharField(max_length=100, verbose_name=u'¿Xtra?')
 
62
 
 
63
    def __unicode__(self):
 
64
        return u'¿Xtra1: %s' % self.xtra
 
65
 
 
66
class ChapterXtra2(models.Model):
 
67
    chap = models.OneToOneField(Chapter, verbose_name=u'¿Chap?')
 
68
    xtra = models.CharField(max_length=100, verbose_name=u'¿Xtra?')
 
69
 
 
70
    def __unicode__(self):
 
71
        return u'¿Xtra2: %s' % self.xtra
 
72
 
 
73
def callable_year(dt_value):
 
74
    return dt_value.year
 
75
callable_year.admin_order_field = 'date'
 
76
 
 
77
class ArticleInline(admin.TabularInline):
 
78
    model = Article
 
79
 
 
80
class ChapterInline(admin.TabularInline):
 
81
    model = Chapter
 
82
 
 
83
class ArticleAdmin(admin.ModelAdmin):
 
84
    list_display = ('content', 'date', callable_year, 'model_year', 'modeladmin_year')
 
85
    list_filter = ('date',)
 
86
 
 
87
    def changelist_view(self, request):
 
88
        "Test that extra_context works"
 
89
        return super(ArticleAdmin, self).changelist_view(
 
90
            request, extra_context={
 
91
                'extra_var': 'Hello!'
 
92
            }
 
93
        )
 
94
 
 
95
    def modeladmin_year(self, obj):
 
96
        return obj.date.year
 
97
    modeladmin_year.admin_order_field = 'date'
 
98
 
 
99
class CustomArticle(models.Model):
 
100
    content = models.TextField()
 
101
    date = models.DateTimeField()
 
102
 
 
103
class CustomArticleAdmin(admin.ModelAdmin):
 
104
    """
 
105
    Tests various hooks for using custom templates and contexts.
 
106
    """
 
107
    change_list_template = 'custom_admin/change_list.html'
 
108
    change_form_template = 'custom_admin/change_form.html'
 
109
    object_history_template = 'custom_admin/object_history.html'
 
110
    delete_confirmation_template = 'custom_admin/delete_confirmation.html'
 
111
 
 
112
    def changelist_view(self, request):
 
113
        "Test that extra_context works"
 
114
        return super(CustomArticleAdmin, self).changelist_view(
 
115
            request, extra_context={
 
116
                'extra_var': 'Hello!'
 
117
            }
 
118
        )
 
119
 
 
120
class ModelWithStringPrimaryKey(models.Model):
 
121
    id = models.CharField(max_length=255, primary_key=True)
 
122
 
 
123
    def __unicode__(self):
 
124
        return self.id
 
125
 
 
126
class Color(models.Model):
 
127
    value = models.CharField(max_length=10)
 
128
    warm = models.BooleanField()
 
129
    def __unicode__(self):
 
130
        return self.value
 
131
 
 
132
class Thing(models.Model):
 
133
    title = models.CharField(max_length=20)
 
134
    color = models.ForeignKey(Color, limit_choices_to={'warm': True})
 
135
    def __unicode__(self):
 
136
        return self.title
 
137
 
 
138
class ThingAdmin(admin.ModelAdmin):
 
139
    list_filter = ('color',)
 
140
 
 
141
class Fabric(models.Model):
 
142
    NG_CHOICES = (
 
143
        ('Textured', (
 
144
                ('x', 'Horizontal'),
 
145
                ('y', 'Vertical'),
 
146
            )
 
147
        ),
 
148
        ('plain', 'Smooth'),
 
149
    )
 
150
    surface = models.CharField(max_length=20, choices=NG_CHOICES)
 
151
 
 
152
class FabricAdmin(admin.ModelAdmin):
 
153
    list_display = ('surface',)
 
154
    list_filter = ('surface',)
 
155
 
 
156
class Person(models.Model):
 
157
    GENDER_CHOICES = (
 
158
        (1, "Male"),
 
159
        (2, "Female"),
 
160
    )
 
161
    name = models.CharField(max_length=100)
 
162
    gender = models.IntegerField(choices=GENDER_CHOICES)
 
163
    alive = models.BooleanField()
 
164
 
 
165
    def __unicode__(self):
 
166
        return self.name
 
167
 
 
168
    class Meta:
 
169
        ordering = ["id"]
 
170
 
 
171
class PersonAdmin(admin.ModelAdmin):
 
172
    list_display = ('name', 'gender', 'alive')
 
173
    list_editable = ('gender', 'alive')
 
174
    list_filter = ('gender',)
 
175
    search_fields = (u'name',)
 
176
    ordering = ["id"]
 
177
    save_as = True
 
178
 
 
179
class Persona(models.Model):
 
180
    """
 
181
    A simple persona associated with accounts, to test inlining of related
 
182
    accounts which inherit from a common accounts class.
 
183
    """
 
184
    name = models.CharField(blank=False,  max_length=80)
 
185
    def __unicode__(self):
 
186
        return self.name
 
187
 
 
188
class Account(models.Model):
 
189
    """
 
190
    A simple, generic account encapsulating the information shared by all
 
191
    types of accounts.
 
192
    """
 
193
    username = models.CharField(blank=False,  max_length=80)
 
194
    persona = models.ForeignKey(Persona, related_name="accounts")
 
195
    servicename = u'generic service'
 
196
 
 
197
    def __unicode__(self):
 
198
        return "%s: %s" % (self.servicename, self.username)
 
199
 
 
200
class FooAccount(Account):
 
201
    """A service-specific account of type Foo."""
 
202
    servicename = u'foo'
 
203
 
 
204
class BarAccount(Account):
 
205
    """A service-specific account of type Bar."""
 
206
    servicename = u'bar'
 
207
 
 
208
class FooAccountAdmin(admin.StackedInline):
 
209
    model = FooAccount
 
210
    extra = 1
 
211
 
 
212
class BarAccountAdmin(admin.StackedInline):
 
213
    model = BarAccount
 
214
    extra = 1
 
215
 
 
216
class PersonaAdmin(admin.ModelAdmin):
 
217
    inlines = (
 
218
        FooAccountAdmin,
 
219
        BarAccountAdmin
 
220
    )
 
221
 
 
222
class Subscriber(models.Model):
 
223
    name = models.CharField(blank=False, max_length=80)
 
224
    email = models.EmailField(blank=False, max_length=175)
 
225
 
 
226
    def __unicode__(self):
 
227
        return "%s (%s)" % (self.name, self.email)
 
228
 
 
229
class SubscriberAdmin(admin.ModelAdmin):
 
230
    actions = ['mail_admin']
 
231
 
 
232
    def mail_admin(self, request, selected):
 
233
        EmailMessage(
 
234
            'Greetings from a ModelAdmin action',
 
235
            'This is the test email from a admin action',
 
236
            'from@example.com',
 
237
            ['to@example.com']
 
238
        ).send()
 
239
 
 
240
class ExternalSubscriber(Subscriber):
 
241
    pass
 
242
 
 
243
class OldSubscriber(Subscriber):
 
244
    pass
 
245
 
 
246
def external_mail(modeladmin, request, selected):
 
247
    EmailMessage(
 
248
        'Greetings from a function action',
 
249
        'This is the test email from a function action',
 
250
        'from@example.com',
 
251
        ['to@example.com']
 
252
    ).send()
 
253
 
 
254
def redirect_to(modeladmin, request, selected):
 
255
    from django.http import HttpResponseRedirect
 
256
    return HttpResponseRedirect('/some-where-else/')
 
257
 
 
258
class ExternalSubscriberAdmin(admin.ModelAdmin):
 
259
    actions = [external_mail, redirect_to]
 
260
 
 
261
class Media(models.Model):
 
262
    name = models.CharField(max_length=60)
 
263
 
 
264
class Podcast(Media):
 
265
    release_date = models.DateField()
 
266
 
 
267
class PodcastAdmin(admin.ModelAdmin):
 
268
    list_display = ('name', 'release_date')
 
269
    list_editable = ('release_date',)
 
270
 
 
271
    ordering = ('name',)
 
272
 
 
273
class Vodcast(Media):
 
274
    media = models.OneToOneField(Media, primary_key=True, parent_link=True)
 
275
    released = models.BooleanField(default=False)
 
276
 
 
277
class VodcastAdmin(admin.ModelAdmin):
 
278
    list_display = ('name', 'released')
 
279
    list_editable = ('released',)
 
280
 
 
281
    ordering = ('name',)
 
282
 
 
283
class Parent(models.Model):
 
284
    name = models.CharField(max_length=128)
 
285
 
 
286
class Child(models.Model):
 
287
    parent = models.ForeignKey(Parent, editable=False)
 
288
    name = models.CharField(max_length=30, blank=True)
 
289
 
 
290
class ChildInline(admin.StackedInline):
 
291
    model = Child
 
292
 
 
293
class ParentAdmin(admin.ModelAdmin):
 
294
    model = Parent
 
295
    inlines = [ChildInline]
 
296
 
 
297
class EmptyModel(models.Model):
 
298
    def __unicode__(self):
 
299
        return "Primary key = %s" % self.id
 
300
 
 
301
class EmptyModelAdmin(admin.ModelAdmin):
 
302
    def queryset(self, request):
 
303
        return super(EmptyModelAdmin, self).queryset(request).filter(pk__gt=1)
 
304
 
 
305
class OldSubscriberAdmin(admin.ModelAdmin):
 
306
    actions = None
 
307
 
 
308
temp_storage = FileSystemStorage(tempfile.mkdtemp())
 
309
UPLOAD_TO = os.path.join(temp_storage.location, 'test_upload')
 
310
 
 
311
class Gallery(models.Model):
 
312
    name = models.CharField(max_length=100)
 
313
 
 
314
class Picture(models.Model):
 
315
    name = models.CharField(max_length=100)
 
316
    image = models.FileField(storage=temp_storage, upload_to='test_upload')
 
317
    gallery = models.ForeignKey(Gallery, related_name="pictures")
 
318
 
 
319
class PictureInline(admin.TabularInline):
 
320
    model = Picture
 
321
    extra = 1
 
322
 
 
323
class GalleryAdmin(admin.ModelAdmin):
 
324
    inlines = [PictureInline]
 
325
 
 
326
class PictureAdmin(admin.ModelAdmin):
 
327
    pass
 
328
 
 
329
class Language(models.Model):
 
330
    iso = models.CharField(max_length=5, primary_key=True)
 
331
    name = models.CharField(max_length=50)
 
332
    english_name = models.CharField(max_length=50)
 
333
    shortlist = models.BooleanField(default=False)
 
334
 
 
335
    class Meta:
 
336
        ordering = ('iso',)
 
337
 
 
338
class LanguageAdmin(admin.ModelAdmin):
 
339
    list_display = ['iso', 'shortlist', 'english_name', 'name']
 
340
    list_editable = ['shortlist']
 
341
 
 
342
# a base class for Recommender and Recommendation
 
343
class Title(models.Model):
 
344
    pass
 
345
 
 
346
class TitleTranslation(models.Model):
 
347
    title = models.ForeignKey(Title)
 
348
    text = models.CharField(max_length=100)
 
349
 
 
350
class Recommender(Title):
 
351
    pass
 
352
 
 
353
class Recommendation(Title):
 
354
    recommender = models.ForeignKey(Recommender)
 
355
 
 
356
class RecommendationAdmin(admin.ModelAdmin):
 
357
    search_fields = ('titletranslation__text', 'recommender__titletranslation__text',)
 
358
 
 
359
class Collector(models.Model):
 
360
    name = models.CharField(max_length=100)
 
361
 
 
362
class Widget(models.Model):
 
363
    owner = models.ForeignKey(Collector)
 
364
    name = models.CharField(max_length=100)
 
365
 
 
366
class DooHickey(models.Model):
 
367
    code = models.CharField(max_length=10, primary_key=True)
 
368
    owner = models.ForeignKey(Collector)
 
369
    name = models.CharField(max_length=100)
 
370
 
 
371
class Grommet(models.Model):
 
372
    code = models.AutoField(primary_key=True)
 
373
    owner = models.ForeignKey(Collector)
 
374
    name = models.CharField(max_length=100)
 
375
 
 
376
class Whatsit(models.Model):
 
377
    index = models.IntegerField(primary_key=True)
 
378
    owner = models.ForeignKey(Collector)
 
379
    name = models.CharField(max_length=100)
 
380
 
 
381
class Doodad(models.Model):
 
382
    name = models.CharField(max_length=100)
 
383
 
 
384
class FancyDoodad(Doodad):
 
385
    owner = models.ForeignKey(Collector)
 
386
    expensive = models.BooleanField(default=True)
 
387
 
 
388
class WidgetInline(admin.StackedInline):
 
389
    model = Widget
 
390
 
 
391
class DooHickeyInline(admin.StackedInline):
 
392
    model = DooHickey
 
393
 
 
394
class GrommetInline(admin.StackedInline):
 
395
    model = Grommet
 
396
 
 
397
class WhatsitInline(admin.StackedInline):
 
398
    model = Whatsit
 
399
 
 
400
class FancyDoodadInline(admin.StackedInline):
 
401
    model = FancyDoodad
 
402
 
 
403
class Category(models.Model):
 
404
    collector = models.ForeignKey(Collector)
 
405
    order = models.PositiveIntegerField()
 
406
 
 
407
    class Meta:
 
408
        ordering = ('order',)
 
409
 
 
410
    def __unicode__(self):
 
411
        return u'%s:o%s' % (self.id, self.order)
 
412
 
 
413
class CategoryAdmin(admin.ModelAdmin):
 
414
    list_display = ('id', 'collector', 'order')
 
415
    list_editable = ('order',)
 
416
 
 
417
class CategoryInline(admin.StackedInline):
 
418
    model = Category
 
419
 
 
420
class CollectorAdmin(admin.ModelAdmin):
 
421
    inlines = [WidgetInline, DooHickeyInline, GrommetInline, WhatsitInline, FancyDoodadInline, CategoryInline]
 
422
 
 
423
admin.site.register(Article, ArticleAdmin)
 
424
admin.site.register(CustomArticle, CustomArticleAdmin)
 
425
admin.site.register(Section, save_as=True, inlines=[ArticleInline])
 
426
admin.site.register(ModelWithStringPrimaryKey)
 
427
admin.site.register(Color)
 
428
admin.site.register(Thing, ThingAdmin)
 
429
admin.site.register(Person, PersonAdmin)
 
430
admin.site.register(Persona, PersonaAdmin)
 
431
admin.site.register(Subscriber, SubscriberAdmin)
 
432
admin.site.register(ExternalSubscriber, ExternalSubscriberAdmin)
 
433
admin.site.register(OldSubscriber, OldSubscriberAdmin)
 
434
admin.site.register(Podcast, PodcastAdmin)
 
435
admin.site.register(Vodcast, VodcastAdmin)
 
436
admin.site.register(Parent, ParentAdmin)
 
437
admin.site.register(EmptyModel, EmptyModelAdmin)
 
438
admin.site.register(Fabric, FabricAdmin)
 
439
admin.site.register(Gallery, GalleryAdmin)
 
440
admin.site.register(Picture, PictureAdmin)
 
441
admin.site.register(Language, LanguageAdmin)
 
442
admin.site.register(Recommendation, RecommendationAdmin)
 
443
admin.site.register(Recommender)
 
444
admin.site.register(Collector, CollectorAdmin)
 
445
admin.site.register(Category, CategoryAdmin)
 
446
 
 
447
# We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
 
448
# That way we cover all four cases:
 
449
#     related ForeignKey object registered in admin
 
450
#     related ForeignKey object not registered in admin
 
451
#     related OneToOne object registered in admin
 
452
#     related OneToOne object not registered in admin
 
453
# when deleting Book so as exercise all four troublesome (w.r.t escaping
 
454
# and calling force_unicode to avoid problems on Python 2.3) paths through
 
455
# contrib.admin.util's get_deleted_objects function.
 
456
admin.site.register(Book, inlines=[ChapterInline])
 
457
admin.site.register(Promo)
 
458
admin.site.register(ChapterXtra1)