1
# -*- coding: utf-8 -*-
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
9
class Section(models.Model):
11
A simple section that links to articles, to test linking to related items
14
name = models.CharField(max_length=100)
16
class Article(models.Model):
18
A simple article to test admin views. Test backwards compatibility.
20
title = models.CharField(max_length=100)
21
content = models.TextField()
22
date = models.DateTimeField()
23
section = models.ForeignKey(Section)
25
def __unicode__(self):
30
model_year.admin_order_field = 'date'
32
class Book(models.Model):
34
A simple book that has chapters.
36
name = models.CharField(max_length=100, verbose_name=u'¿Name?')
38
def __unicode__(self):
41
class Promo(models.Model):
42
name = models.CharField(max_length=100, verbose_name=u'¿Name?')
43
book = models.ForeignKey(Book)
45
def __unicode__(self):
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)
53
def __unicode__(self):
57
verbose_name = u'¿Chapter?'
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?')
63
def __unicode__(self):
64
return u'¿Xtra1: %s' % self.xtra
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?')
70
def __unicode__(self):
71
return u'¿Xtra2: %s' % self.xtra
73
def callable_year(dt_value):
75
callable_year.admin_order_field = 'date'
77
class ArticleInline(admin.TabularInline):
80
class ChapterInline(admin.TabularInline):
83
class ArticleAdmin(admin.ModelAdmin):
84
list_display = ('content', 'date', callable_year, 'model_year', 'modeladmin_year')
85
list_filter = ('date',)
87
def changelist_view(self, request):
88
"Test that extra_context works"
89
return super(ArticleAdmin, self).changelist_view(
90
request, extra_context={
95
def modeladmin_year(self, obj):
97
modeladmin_year.admin_order_field = 'date'
99
class CustomArticle(models.Model):
100
content = models.TextField()
101
date = models.DateTimeField()
103
class CustomArticleAdmin(admin.ModelAdmin):
105
Tests various hooks for using custom templates and contexts.
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'
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!'
120
class ModelWithStringPrimaryKey(models.Model):
121
id = models.CharField(max_length=255, primary_key=True)
123
def __unicode__(self):
126
class Color(models.Model):
127
value = models.CharField(max_length=10)
128
warm = models.BooleanField()
129
def __unicode__(self):
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):
138
class ThingAdmin(admin.ModelAdmin):
139
list_filter = ('color',)
141
class Fabric(models.Model):
150
surface = models.CharField(max_length=20, choices=NG_CHOICES)
152
class FabricAdmin(admin.ModelAdmin):
153
list_display = ('surface',)
154
list_filter = ('surface',)
156
class Person(models.Model):
161
name = models.CharField(max_length=100)
162
gender = models.IntegerField(choices=GENDER_CHOICES)
163
alive = models.BooleanField()
165
def __unicode__(self):
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',)
179
class Persona(models.Model):
181
A simple persona associated with accounts, to test inlining of related
182
accounts which inherit from a common accounts class.
184
name = models.CharField(blank=False, max_length=80)
185
def __unicode__(self):
188
class Account(models.Model):
190
A simple, generic account encapsulating the information shared by all
193
username = models.CharField(blank=False, max_length=80)
194
persona = models.ForeignKey(Persona, related_name="accounts")
195
servicename = u'generic service'
197
def __unicode__(self):
198
return "%s: %s" % (self.servicename, self.username)
200
class FooAccount(Account):
201
"""A service-specific account of type Foo."""
204
class BarAccount(Account):
205
"""A service-specific account of type Bar."""
208
class FooAccountAdmin(admin.StackedInline):
212
class BarAccountAdmin(admin.StackedInline):
216
class PersonaAdmin(admin.ModelAdmin):
222
class Subscriber(models.Model):
223
name = models.CharField(blank=False, max_length=80)
224
email = models.EmailField(blank=False, max_length=175)
226
def __unicode__(self):
227
return "%s (%s)" % (self.name, self.email)
229
class SubscriberAdmin(admin.ModelAdmin):
230
actions = ['mail_admin']
232
def mail_admin(self, request, selected):
234
'Greetings from a ModelAdmin action',
235
'This is the test email from a admin action',
240
class ExternalSubscriber(Subscriber):
243
class OldSubscriber(Subscriber):
246
def external_mail(modeladmin, request, selected):
248
'Greetings from a function action',
249
'This is the test email from a function action',
254
def redirect_to(modeladmin, request, selected):
255
from django.http import HttpResponseRedirect
256
return HttpResponseRedirect('/some-where-else/')
258
class ExternalSubscriberAdmin(admin.ModelAdmin):
259
actions = [external_mail, redirect_to]
261
class Media(models.Model):
262
name = models.CharField(max_length=60)
264
class Podcast(Media):
265
release_date = models.DateField()
267
class PodcastAdmin(admin.ModelAdmin):
268
list_display = ('name', 'release_date')
269
list_editable = ('release_date',)
273
class Vodcast(Media):
274
media = models.OneToOneField(Media, primary_key=True, parent_link=True)
275
released = models.BooleanField(default=False)
277
class VodcastAdmin(admin.ModelAdmin):
278
list_display = ('name', 'released')
279
list_editable = ('released',)
283
class Parent(models.Model):
284
name = models.CharField(max_length=128)
286
class Child(models.Model):
287
parent = models.ForeignKey(Parent, editable=False)
288
name = models.CharField(max_length=30, blank=True)
290
class ChildInline(admin.StackedInline):
293
class ParentAdmin(admin.ModelAdmin):
295
inlines = [ChildInline]
297
class EmptyModel(models.Model):
298
def __unicode__(self):
299
return "Primary key = %s" % self.id
301
class EmptyModelAdmin(admin.ModelAdmin):
302
def queryset(self, request):
303
return super(EmptyModelAdmin, self).queryset(request).filter(pk__gt=1)
305
class OldSubscriberAdmin(admin.ModelAdmin):
308
temp_storage = FileSystemStorage(tempfile.mkdtemp())
309
UPLOAD_TO = os.path.join(temp_storage.location, 'test_upload')
311
class Gallery(models.Model):
312
name = models.CharField(max_length=100)
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")
319
class PictureInline(admin.TabularInline):
323
class GalleryAdmin(admin.ModelAdmin):
324
inlines = [PictureInline]
326
class PictureAdmin(admin.ModelAdmin):
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)
338
class LanguageAdmin(admin.ModelAdmin):
339
list_display = ['iso', 'shortlist', 'english_name', 'name']
340
list_editable = ['shortlist']
342
# a base class for Recommender and Recommendation
343
class Title(models.Model):
346
class TitleTranslation(models.Model):
347
title = models.ForeignKey(Title)
348
text = models.CharField(max_length=100)
350
class Recommender(Title):
353
class Recommendation(Title):
354
recommender = models.ForeignKey(Recommender)
356
class RecommendationAdmin(admin.ModelAdmin):
357
search_fields = ('titletranslation__text', 'recommender__titletranslation__text',)
359
class Collector(models.Model):
360
name = models.CharField(max_length=100)
362
class Widget(models.Model):
363
owner = models.ForeignKey(Collector)
364
name = models.CharField(max_length=100)
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)
371
class Grommet(models.Model):
372
code = models.AutoField(primary_key=True)
373
owner = models.ForeignKey(Collector)
374
name = models.CharField(max_length=100)
376
class Whatsit(models.Model):
377
index = models.IntegerField(primary_key=True)
378
owner = models.ForeignKey(Collector)
379
name = models.CharField(max_length=100)
381
class Doodad(models.Model):
382
name = models.CharField(max_length=100)
384
class FancyDoodad(Doodad):
385
owner = models.ForeignKey(Collector)
386
expensive = models.BooleanField(default=True)
388
class WidgetInline(admin.StackedInline):
391
class DooHickeyInline(admin.StackedInline):
394
class GrommetInline(admin.StackedInline):
397
class WhatsitInline(admin.StackedInline):
400
class FancyDoodadInline(admin.StackedInline):
403
class Category(models.Model):
404
collector = models.ForeignKey(Collector)
405
order = models.PositiveIntegerField()
408
ordering = ('order',)
410
def __unicode__(self):
411
return u'%s:o%s' % (self.id, self.order)
413
class CategoryAdmin(admin.ModelAdmin):
414
list_display = ('id', 'collector', 'order')
415
list_editable = ('order',)
417
class CategoryInline(admin.StackedInline):
420
class CollectorAdmin(admin.ModelAdmin):
421
inlines = [WidgetInline, DooHickeyInline, GrommetInline, WhatsitInline, FancyDoodadInline, CategoryInline]
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)
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)