PageRenderTime 434ms CodeModel.GetById 101ms app.highlight 189ms RepoModel.GetById 92ms app.codeStats 2ms

/tests/regressiontests/admin_views/models.py

https://code.google.com/p/mango-py/
Python | 820 lines | 807 code | 5 blank | 8 comment | 2 complexity | 3fe9c9c214bf9db04ae571402182bb73 MD5 | raw file
  1# -*- coding: utf-8 -*-
  2import datetime
  3import tempfile
  4import os
  5
  6from django.contrib import admin
  7from django.core.files.storage import FileSystemStorage
  8from django.contrib.admin.views.main import ChangeList
  9from django.core.mail import EmailMessage
 10from django.db import models
 11from django import forms
 12from django.forms.models import BaseModelFormSet
 13from django.contrib.auth.models import User
 14from django.contrib.contenttypes import generic
 15from django.contrib.contenttypes.models import ContentType
 16
 17class Section(models.Model):
 18    """
 19    A simple section that links to articles, to test linking to related items
 20    in admin views.
 21    """
 22    name = models.CharField(max_length=100)
 23
 24class Article(models.Model):
 25    """
 26    A simple article to test admin views. Test backwards compatibility.
 27    """
 28    title = models.CharField(max_length=100)
 29    content = models.TextField()
 30    date = models.DateTimeField()
 31    section = models.ForeignKey(Section, null=True, blank=True)
 32
 33    def __unicode__(self):
 34        return self.title
 35
 36    def model_year(self):
 37        return self.date.year
 38    model_year.admin_order_field = 'date'
 39    model_year.short_description = ''
 40
 41class Book(models.Model):
 42    """
 43    A simple book that has chapters.
 44    """
 45    name = models.CharField(max_length=100, verbose_name=u'żName?')
 46
 47    def __unicode__(self):
 48        return self.name
 49
 50class Promo(models.Model):
 51    name = models.CharField(max_length=100, verbose_name=u'żName?')
 52    book = models.ForeignKey(Book)
 53
 54    def __unicode__(self):
 55        return self.name
 56
 57class Chapter(models.Model):
 58    title = models.CharField(max_length=100, verbose_name=u'żTitle?')
 59    content = models.TextField()
 60    book = models.ForeignKey(Book)
 61
 62    def __unicode__(self):
 63        return self.title
 64
 65    class Meta:
 66        # Use a utf-8 bytestring to ensure it works (see #11710)
 67        verbose_name = 'żChapter?'
 68
 69class ChapterXtra1(models.Model):
 70    chap = models.OneToOneField(Chapter, verbose_name=u'żChap?')
 71    xtra = models.CharField(max_length=100, verbose_name=u'żXtra?')
 72
 73    def __unicode__(self):
 74        return u'żXtra1: %s' % self.xtra
 75
 76class ChapterXtra2(models.Model):
 77    chap = models.OneToOneField(Chapter, verbose_name=u'żChap?')
 78    xtra = models.CharField(max_length=100, verbose_name=u'żXtra?')
 79
 80    def __unicode__(self):
 81        return u'żXtra2: %s' % self.xtra
 82
 83def callable_year(dt_value):
 84    return dt_value.year
 85callable_year.admin_order_field = 'date'
 86
 87class ArticleInline(admin.TabularInline):
 88    model = Article
 89
 90class ChapterInline(admin.TabularInline):
 91    model = Chapter
 92
 93class ChapterXtra1Admin(admin.ModelAdmin):
 94    list_filter = ('chap',
 95                   'chap__title',
 96                   'chap__book',
 97                   'chap__book__name',
 98                   'chap__book__promo',
 99                   'chap__book__promo__name',)
100
101class ArticleAdmin(admin.ModelAdmin):
102    list_display = ('content', 'date', callable_year, 'model_year', 'modeladmin_year')
103    list_filter = ('date', 'section')
104
105    def changelist_view(self, request):
106        "Test that extra_context works"
107        return super(ArticleAdmin, self).changelist_view(
108            request, extra_context={
109                'extra_var': 'Hello!'
110            }
111        )
112
113    def modeladmin_year(self, obj):
114        return obj.date.year
115    modeladmin_year.admin_order_field = 'date'
116    modeladmin_year.short_description = None
117
118    def delete_model(self, request, obj):
119        EmailMessage(
120            'Greetings from a deleted object',
121            'I hereby inform you that some user deleted me',
122            'from@example.com',
123            ['to@example.com']
124        ).send()
125        return super(ArticleAdmin, self).delete_model(request, obj)
126
127    def save_model(self, request, obj, form, change=True):
128        EmailMessage(
129            'Greetings from a created object',
130            'I hereby inform you that some user created me',
131            'from@example.com',
132            ['to@example.com']
133        ).send()
134        return super(ArticleAdmin, self).save_model(request, obj, form, change)
135
136class RowLevelChangePermissionModel(models.Model):
137    name = models.CharField(max_length=100, blank=True)
138
139class RowLevelChangePermissionModelAdmin(admin.ModelAdmin):
140    def has_change_permission(self, request, obj=None):
141        """ Only allow changing objects with even id number """
142        return request.user.is_staff and (obj is not None) and (obj.id % 2 == 0)
143
144class CustomArticle(models.Model):
145    content = models.TextField()
146    date = models.DateTimeField()
147
148class CustomArticleAdmin(admin.ModelAdmin):
149    """
150    Tests various hooks for using custom templates and contexts.
151    """
152    change_list_template = 'custom_admin/change_list.html'
153    change_form_template = 'custom_admin/change_form.html'
154    add_form_template = 'custom_admin/add_form.html'
155    object_history_template = 'custom_admin/object_history.html'
156    delete_confirmation_template = 'custom_admin/delete_confirmation.html'
157    delete_selected_confirmation_template = 'custom_admin/delete_selected_confirmation.html'
158
159    def changelist_view(self, request):
160        "Test that extra_context works"
161        return super(CustomArticleAdmin, self).changelist_view(
162            request, extra_context={
163                'extra_var': 'Hello!'
164            }
165        )
166
167class ModelWithStringPrimaryKey(models.Model):
168    id = models.CharField(max_length=255, primary_key=True)
169
170    def __unicode__(self):
171        return self.id
172
173class Color(models.Model):
174    value = models.CharField(max_length=10)
175    warm = models.BooleanField()
176    def __unicode__(self):
177        return self.value
178
179class Thing(models.Model):
180    title = models.CharField(max_length=20)
181    color = models.ForeignKey(Color, limit_choices_to={'warm': True})
182    def __unicode__(self):
183        return self.title
184
185class ThingAdmin(admin.ModelAdmin):
186    list_filter = ('color__warm', 'color__value')
187
188class Actor(models.Model):
189    name = models.CharField(max_length=50)
190    age = models.IntegerField()
191    def __unicode__(self):
192        return self.name
193
194class Inquisition(models.Model):
195    expected = models.BooleanField()
196    leader = models.ForeignKey(Actor)
197    country = models.CharField(max_length=20)
198
199    def __unicode__(self):
200        return u"by %s from %s" % (self.leader, self.country)
201
202class InquisitionAdmin(admin.ModelAdmin):
203    list_display = ('leader', 'country', 'expected')
204
205class Sketch(models.Model):
206    title = models.CharField(max_length=100)
207    inquisition = models.ForeignKey(Inquisition, limit_choices_to={'leader__name': 'Palin',
208                                                                   'leader__age': 27,
209                                                                   'expected': False,
210                                                                   })
211
212    def __unicode__(self):
213        return self.title
214
215class SketchAdmin(admin.ModelAdmin):
216    raw_id_fields = ('inquisition',)
217
218class Fabric(models.Model):
219    NG_CHOICES = (
220        ('Textured', (
221                ('x', 'Horizontal'),
222                ('y', 'Vertical'),
223            )
224        ),
225        ('plain', 'Smooth'),
226    )
227    surface = models.CharField(max_length=20, choices=NG_CHOICES)
228
229class FabricAdmin(admin.ModelAdmin):
230    list_display = ('surface',)
231    list_filter = ('surface',)
232
233class Person(models.Model):
234    GENDER_CHOICES = (
235        (1, "Male"),
236        (2, "Female"),
237    )
238    name = models.CharField(max_length=100)
239    gender = models.IntegerField(choices=GENDER_CHOICES)
240    age = models.IntegerField(default=21)
241    alive = models.BooleanField()
242
243    def __unicode__(self):
244        return self.name
245
246    class Meta:
247        ordering = ["id"]
248
249class BasePersonModelFormSet(BaseModelFormSet):
250    def clean(self):
251        for person_dict in self.cleaned_data:
252            person = person_dict.get('id')
253            alive = person_dict.get('alive')
254            if person and alive and person.name == "Grace Hopper":
255                raise forms.ValidationError("Grace is not a Zombie")
256
257class PersonAdmin(admin.ModelAdmin):
258    list_display = ('name', 'gender', 'alive')
259    list_editable = ('gender', 'alive')
260    list_filter = ('gender',)
261    search_fields = ('^name',)
262    ordering = ["id"]
263    save_as = True
264
265    def get_changelist_formset(self, request, **kwargs):
266        return super(PersonAdmin, self).get_changelist_formset(request,
267            formset=BasePersonModelFormSet, **kwargs)
268
269
270class Persona(models.Model):
271    """
272    A simple persona associated with accounts, to test inlining of related
273    accounts which inherit from a common accounts class.
274    """
275    name = models.CharField(blank=False,  max_length=80)
276    def __unicode__(self):
277        return self.name
278
279class Account(models.Model):
280    """
281    A simple, generic account encapsulating the information shared by all
282    types of accounts.
283    """
284    username = models.CharField(blank=False,  max_length=80)
285    persona = models.ForeignKey(Persona, related_name="accounts")
286    servicename = u'generic service'
287
288    def __unicode__(self):
289        return "%s: %s" % (self.servicename, self.username)
290
291class FooAccount(Account):
292    """A service-specific account of type Foo."""
293    servicename = u'foo'
294
295class BarAccount(Account):
296    """A service-specific account of type Bar."""
297    servicename = u'bar'
298
299class FooAccountAdmin(admin.StackedInline):
300    model = FooAccount
301    extra = 1
302
303class BarAccountAdmin(admin.StackedInline):
304    model = BarAccount
305    extra = 1
306
307class PersonaAdmin(admin.ModelAdmin):
308    inlines = (
309        FooAccountAdmin,
310        BarAccountAdmin
311    )
312
313class Subscriber(models.Model):
314    name = models.CharField(blank=False, max_length=80)
315    email = models.EmailField(blank=False, max_length=175)
316
317    def __unicode__(self):
318        return "%s (%s)" % (self.name, self.email)
319
320class SubscriberAdmin(admin.ModelAdmin):
321    actions = ['mail_admin']
322
323    def mail_admin(self, request, selected):
324        EmailMessage(
325            'Greetings from a ModelAdmin action',
326            'This is the test email from a admin action',
327            'from@example.com',
328            ['to@example.com']
329        ).send()
330
331class ExternalSubscriber(Subscriber):
332    pass
333
334class OldSubscriber(Subscriber):
335    pass
336
337def external_mail(modeladmin, request, selected):
338    EmailMessage(
339        'Greetings from a function action',
340        'This is the test email from a function action',
341        'from@example.com',
342        ['to@example.com']
343    ).send()
344
345def redirect_to(modeladmin, request, selected):
346    from django.http import HttpResponseRedirect
347    return HttpResponseRedirect('/some-where-else/')
348
349class ExternalSubscriberAdmin(admin.ModelAdmin):
350    actions = [external_mail, redirect_to]
351
352class Media(models.Model):
353    name = models.CharField(max_length=60)
354
355class Podcast(Media):
356    release_date = models.DateField()
357
358class PodcastAdmin(admin.ModelAdmin):
359    list_display = ('name', 'release_date')
360    list_editable = ('release_date',)
361    date_hierarchy = 'release_date'
362    ordering = ('name',)
363
364class Vodcast(Media):
365    media = models.OneToOneField(Media, primary_key=True, parent_link=True)
366    released = models.BooleanField(default=False)
367
368class VodcastAdmin(admin.ModelAdmin):
369    list_display = ('name', 'released')
370    list_editable = ('released',)
371
372    ordering = ('name',)
373
374class Parent(models.Model):
375    name = models.CharField(max_length=128)
376
377class Child(models.Model):
378    parent = models.ForeignKey(Parent, editable=False)
379    name = models.CharField(max_length=30, blank=True)
380
381class ChildInline(admin.StackedInline):
382    model = Child
383
384class ParentAdmin(admin.ModelAdmin):
385    model = Parent
386    inlines = [ChildInline]
387
388class EmptyModel(models.Model):
389    def __unicode__(self):
390        return "Primary key = %s" % self.id
391
392class EmptyModelAdmin(admin.ModelAdmin):
393    def queryset(self, request):
394        return super(EmptyModelAdmin, self).queryset(request).filter(pk__gt=1)
395
396class OldSubscriberAdmin(admin.ModelAdmin):
397    actions = None
398
399temp_storage = FileSystemStorage(tempfile.mkdtemp())
400UPLOAD_TO = os.path.join(temp_storage.location, 'test_upload')
401
402class Gallery(models.Model):
403    name = models.CharField(max_length=100)
404
405class Picture(models.Model):
406    name = models.CharField(max_length=100)
407    image = models.FileField(storage=temp_storage, upload_to='test_upload')
408    gallery = models.ForeignKey(Gallery, related_name="pictures")
409
410class PictureInline(admin.TabularInline):
411    model = Picture
412    extra = 1
413
414class GalleryAdmin(admin.ModelAdmin):
415    inlines = [PictureInline]
416
417class PictureAdmin(admin.ModelAdmin):
418    pass
419
420class Language(models.Model):
421    iso = models.CharField(max_length=5, primary_key=True)
422    name = models.CharField(max_length=50)
423    english_name = models.CharField(max_length=50)
424    shortlist = models.BooleanField(default=False)
425
426    class Meta:
427        ordering = ('iso',)
428
429class LanguageAdmin(admin.ModelAdmin):
430    list_display = ['iso', 'shortlist', 'english_name', 'name']
431    list_editable = ['shortlist']
432
433# a base class for Recommender and Recommendation
434class Title(models.Model):
435    pass
436
437class TitleTranslation(models.Model):
438    title = models.ForeignKey(Title)
439    text = models.CharField(max_length=100)
440
441class Recommender(Title):
442    pass
443
444class Recommendation(Title):
445    recommender = models.ForeignKey(Recommender)
446
447class RecommendationAdmin(admin.ModelAdmin):
448    search_fields = ('=titletranslation__text', '=recommender__titletranslation__text',)
449
450class Collector(models.Model):
451    name = models.CharField(max_length=100)
452
453class Widget(models.Model):
454    owner = models.ForeignKey(Collector)
455    name = models.CharField(max_length=100)
456
457class DooHickey(models.Model):
458    code = models.CharField(max_length=10, primary_key=True)
459    owner = models.ForeignKey(Collector)
460    name = models.CharField(max_length=100)
461
462class Grommet(models.Model):
463    code = models.AutoField(primary_key=True)
464    owner = models.ForeignKey(Collector)
465    name = models.CharField(max_length=100)
466
467class Whatsit(models.Model):
468    index = models.IntegerField(primary_key=True)
469    owner = models.ForeignKey(Collector)
470    name = models.CharField(max_length=100)
471
472class Doodad(models.Model):
473    name = models.CharField(max_length=100)
474
475class FancyDoodad(Doodad):
476    owner = models.ForeignKey(Collector)
477    expensive = models.BooleanField(default=True)
478
479class WidgetInline(admin.StackedInline):
480    model = Widget
481
482class DooHickeyInline(admin.StackedInline):
483    model = DooHickey
484
485class GrommetInline(admin.StackedInline):
486    model = Grommet
487
488class WhatsitInline(admin.StackedInline):
489    model = Whatsit
490
491class FancyDoodadInline(admin.StackedInline):
492    model = FancyDoodad
493
494class Category(models.Model):
495    collector = models.ForeignKey(Collector)
496    order = models.PositiveIntegerField()
497
498    class Meta:
499        ordering = ('order',)
500
501    def __unicode__(self):
502        return u'%s:o%s' % (self.id, self.order)
503
504class CategoryAdmin(admin.ModelAdmin):
505    list_display = ('id', 'collector', 'order')
506    list_editable = ('order',)
507
508class CategoryInline(admin.StackedInline):
509    model = Category
510
511class CollectorAdmin(admin.ModelAdmin):
512    inlines = [
513        WidgetInline, DooHickeyInline, GrommetInline, WhatsitInline,
514        FancyDoodadInline, CategoryInline
515    ]
516
517class Link(models.Model):
518    posted = models.DateField(
519        default=lambda: datetime.date.today() - datetime.timedelta(days=7)
520    )
521    url = models.URLField()
522    post = models.ForeignKey("Post")
523
524
525class LinkInline(admin.TabularInline):
526    model = Link
527    extra = 1
528
529    readonly_fields = ("posted",)
530
531
532class Post(models.Model):
533    title = models.CharField(max_length=100, help_text="Some help text for the title (with unicode Š??Ž?žš?)")
534    content = models.TextField(help_text="Some help text for the content (with unicode Š??Ž?žš?)")
535    posted = models.DateField(
536            default=datetime.date.today,
537            help_text="Some help text for the date (with unicode Š??Ž?žš?)"
538    )
539    public = models.NullBooleanField()
540
541    def awesomeness_level(self):
542        return "Very awesome."
543
544class PostAdmin(admin.ModelAdmin):
545    list_display = ['title', 'public']
546    readonly_fields = ('posted', 'awesomeness_level', 'coolness', 'value', lambda obj: "foo")
547
548    inlines = [
549        LinkInline
550    ]
551
552    def coolness(self, instance):
553        if instance.pk:
554            return "%d amount of cool." % instance.pk
555        else:
556            return "Unkown coolness."
557
558    def value(self, instance):
559        return 1000
560    value.short_description = 'Value in $US'
561
562class Gadget(models.Model):
563    name = models.CharField(max_length=100)
564
565    def __unicode__(self):
566        return self.name
567
568class CustomChangeList(ChangeList):
569    def get_query_set(self):
570        return self.root_query_set.filter(pk=9999) # Does not exist
571
572class GadgetAdmin(admin.ModelAdmin):
573    def get_changelist(self, request, **kwargs):
574        return CustomChangeList
575
576class Villain(models.Model):
577    name = models.CharField(max_length=100)
578
579    def __unicode__(self):
580        return self.name
581
582class SuperVillain(Villain):
583    pass
584
585class FunkyTag(models.Model):
586    "Because we all know there's only one real use case for GFKs."
587    name = models.CharField(max_length=25)
588    content_type = models.ForeignKey(ContentType)
589    object_id = models.PositiveIntegerField()
590    content_object = generic.GenericForeignKey('content_type', 'object_id')
591
592    def __unicode__(self):
593        return self.name
594
595class Plot(models.Model):
596    name = models.CharField(max_length=100)
597    team_leader = models.ForeignKey(Villain, related_name='lead_plots')
598    contact = models.ForeignKey(Villain, related_name='contact_plots')
599    tags = generic.GenericRelation(FunkyTag)
600
601    def __unicode__(self):
602        return self.name
603
604class PlotDetails(models.Model):
605    details = models.CharField(max_length=100)
606    plot = models.OneToOneField(Plot)
607
608    def __unicode__(self):
609        return self.details
610
611class SecretHideout(models.Model):
612    """ Secret! Not registered with the admin! """
613    location = models.CharField(max_length=100)
614    villain = models.ForeignKey(Villain)
615
616    def __unicode__(self):
617        return self.location
618
619class SuperSecretHideout(models.Model):
620    """ Secret! Not registered with the admin! """
621    location = models.CharField(max_length=100)
622    supervillain = models.ForeignKey(SuperVillain)
623
624    def __unicode__(self):
625        return self.location
626
627class CyclicOne(models.Model):
628    name = models.CharField(max_length=25)
629    two = models.ForeignKey('CyclicTwo')
630
631    def __unicode__(self):
632        return self.name
633
634class CyclicTwo(models.Model):
635    name = models.CharField(max_length=25)
636    one = models.ForeignKey(CyclicOne)
637
638    def __unicode__(self):
639        return self.name
640
641class Topping(models.Model):
642    name = models.CharField(max_length=20)
643
644class Pizza(models.Model):
645    name = models.CharField(max_length=20)
646    toppings = models.ManyToManyField('Topping')
647
648class PizzaAdmin(admin.ModelAdmin):
649    readonly_fields = ('toppings',)
650
651class Album(models.Model):
652    owner = models.ForeignKey(User)
653    title = models.CharField(max_length=30)
654
655class AlbumAdmin(admin.ModelAdmin):
656    list_filter = ['title']
657
658class Employee(Person):
659    code = models.CharField(max_length=20)
660
661class WorkHour(models.Model):
662    datum = models.DateField()
663    employee = models.ForeignKey(Employee)
664
665class WorkHourAdmin(admin.ModelAdmin):
666    list_display = ('datum', 'employee')
667    list_filter = ('employee',)
668
669class Question(models.Model):
670    question = models.CharField(max_length=20)
671
672class Answer(models.Model):
673    question = models.ForeignKey(Question, on_delete=models.PROTECT)
674    answer = models.CharField(max_length=20)
675
676    def __unicode__(self):
677        return self.answer
678
679class Reservation(models.Model):
680    start_date = models.DateTimeField()
681    price = models.IntegerField()
682
683
684DRIVER_CHOICES = (
685    (u'bill', 'Bill G'),
686    (u'steve', 'Steve J'),
687)
688
689RESTAURANT_CHOICES = (
690    (u'indian', u'A Taste of India'),
691    (u'thai', u'Thai Pography'),
692    (u'pizza', u'Pizza Mama'),
693)
694
695class FoodDelivery(models.Model):
696    reference = models.CharField(max_length=100)
697    driver = models.CharField(max_length=100, choices=DRIVER_CHOICES, blank=True)
698    restaurant = models.CharField(max_length=100, choices=RESTAURANT_CHOICES, blank=True)
699
700    class Meta:
701        unique_together = (("driver", "restaurant"),)
702
703class FoodDeliveryAdmin(admin.ModelAdmin):
704    list_display=('reference', 'driver', 'restaurant')
705    list_editable = ('driver', 'restaurant')
706
707class Paper(models.Model):
708    title = models.CharField(max_length=30)
709    author = models.CharField(max_length=30, blank=True, null=True)
710
711class CoverLetter(models.Model):
712    author = models.CharField(max_length=30)
713    date_written = models.DateField(null=True, blank=True)
714
715    def __unicode__(self):
716        return self.author
717
718class PaperAdmin(admin.ModelAdmin):
719    """
720    A ModelAdin with a custom queryset() method that uses only(), to test
721    verbose_name display in messages shown after adding Paper instances.
722    """
723
724    def queryset(self, request):
725        return super(PaperAdmin, self).queryset(request).only('title')
726
727class CoverLetterAdmin(admin.ModelAdmin):
728    """
729    A ModelAdin with a custom queryset() method that uses only(), to test
730    verbose_name display in messages shown after adding CoverLetter instances.
731    Note that the CoverLetter model defines a __unicode__ method.
732    """
733
734    def queryset(self, request):
735        #return super(CoverLetterAdmin, self).queryset(request).only('author')
736        return super(CoverLetterAdmin, self).queryset(request).defer('date_written')
737
738class Story(models.Model):
739    title = models.CharField(max_length=100)
740    content = models.TextField()
741
742class StoryForm(forms.ModelForm):
743    class Meta:
744        widgets = {'title': forms.HiddenInput}
745
746class StoryAdmin(admin.ModelAdmin):
747    list_display = ('id', 'title', 'content')
748    list_display_links = ('title',) # 'id' not in list_display_links
749    list_editable = ('content', )
750    form = StoryForm
751
752class OtherStory(models.Model):
753    title = models.CharField(max_length=100)
754    content = models.TextField()
755
756class OtherStoryAdmin(admin.ModelAdmin):
757    list_display = ('id', 'title', 'content')
758    list_display_links = ('title', 'id') # 'id' in list_display_links
759    list_editable = ('content', )
760
761admin.site.register(Article, ArticleAdmin)
762admin.site.register(CustomArticle, CustomArticleAdmin)
763admin.site.register(Section, save_as=True, inlines=[ArticleInline])
764admin.site.register(ModelWithStringPrimaryKey)
765admin.site.register(Color)
766admin.site.register(Thing, ThingAdmin)
767admin.site.register(Actor)
768admin.site.register(Inquisition, InquisitionAdmin)
769admin.site.register(Sketch, SketchAdmin)
770admin.site.register(Person, PersonAdmin)
771admin.site.register(Persona, PersonaAdmin)
772admin.site.register(Subscriber, SubscriberAdmin)
773admin.site.register(ExternalSubscriber, ExternalSubscriberAdmin)
774admin.site.register(OldSubscriber, OldSubscriberAdmin)
775admin.site.register(Podcast, PodcastAdmin)
776admin.site.register(Vodcast, VodcastAdmin)
777admin.site.register(Parent, ParentAdmin)
778admin.site.register(EmptyModel, EmptyModelAdmin)
779admin.site.register(Fabric, FabricAdmin)
780admin.site.register(Gallery, GalleryAdmin)
781admin.site.register(Picture, PictureAdmin)
782admin.site.register(Language, LanguageAdmin)
783admin.site.register(Recommendation, RecommendationAdmin)
784admin.site.register(Recommender)
785admin.site.register(Collector, CollectorAdmin)
786admin.site.register(Category, CategoryAdmin)
787admin.site.register(Post, PostAdmin)
788admin.site.register(Gadget, GadgetAdmin)
789admin.site.register(Villain)
790admin.site.register(SuperVillain)
791admin.site.register(Plot)
792admin.site.register(PlotDetails)
793admin.site.register(CyclicOne)
794admin.site.register(CyclicTwo)
795admin.site.register(WorkHour, WorkHourAdmin)
796admin.site.register(Reservation)
797admin.site.register(FoodDelivery, FoodDeliveryAdmin)
798admin.site.register(RowLevelChangePermissionModel, RowLevelChangePermissionModelAdmin)
799admin.site.register(Paper, PaperAdmin)
800admin.site.register(CoverLetter, CoverLetterAdmin)
801admin.site.register(Story, StoryAdmin)
802admin.site.register(OtherStory, OtherStoryAdmin)
803
804# We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
805# That way we cover all four cases:
806#     related ForeignKey object registered in admin
807#     related ForeignKey object not registered in admin
808#     related OneToOne object registered in admin
809#     related OneToOne object not registered in admin
810# when deleting Book so as exercise all four troublesome (w.r.t escaping
811# and calling force_unicode to avoid problems on Python 2.3) paths through
812# contrib.admin.util's get_deleted_objects function.
813admin.site.register(Book, inlines=[ChapterInline])
814admin.site.register(Promo)
815admin.site.register(ChapterXtra1, ChapterXtra1Admin)
816admin.site.register(Pizza, PizzaAdmin)
817admin.site.register(Topping)
818admin.site.register(Album, AlbumAdmin)
819admin.site.register(Question)
820admin.site.register(Answer)