Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I know which child class a Django model object is when selected through the parent class?
    primarykey
    data
    text
    <p>I have a main <code>Event</code> class, and four event types. Each of them is a subclass of (at least) <code>Event</code>. On an event's detail page, I am adding a link back to the admin interface for a given event to save the time of searching in the admin. Unfortunately, regardless of child class, the events are selected from the parent <code>Event</code> class. My solution to this problem was to duck type, which I find to be absolutely awful in this instance. <strong>I am hoping there is a more elegant and easy-to-maintain solution to my problem.</strong></p> <p>Model:</p> <pre><code>class Event(models.Model): ... class ListedEvent(Event): .... class RSVPEvent(Event): .... class TicketedEvent(Event): .... class TicketedConcert(TicketedEvent): .... </code></pre> <p>To see event details, the URL passes a venue slug and event name slug. This is enough info to isolate a single event from the parent <code>Event</code> model across all the child events. It also lets me keep the event type out of the URL, making them simpler and more friendly.</p> <pre><code>@render_to('events/event_details.html') def event_details(request, venue, slug): """ Detail view of an event. """ try: event = Event.objects.select_related( 'listedevent', 'rsvpevent', 'ticketedevent', 'ticketedconcert', 'venue', 'sites', 'dj', ).get( slug=slug, venue__slug=venue, ) except Event.DoesNotExist: raise Http404 return {'event': event} </code></pre> <p>Before I went back and realized that I was using the parent <code>Event</code> model, this solution was much more elegant and worked fine in the shell assuming I select an event from its actual model (property of parent class <code>Event</code>):</p> <pre><code>@property def admin_link(self): et = self.__class__.__name__.lower() # ALWAYS: et == 'event', reverse() fails, returns '' return reverse('admin:events_%s_change' % et, args=(self.id,)) </code></pre> <p>My current solution (property of parent class <code>Event</code>):</p> <pre><code>@property def admin_link(self): duck = None try: duck = self.ticketedevent.ticketedconcert.artist_name return reverse( 'admin:events_ticketedconcert_change', args=(self.id,) ) except: pass try: duck = self.ticketedevent.max_tickets return reverse( 'admin:events_ticketedevent_change', args=(self.id,) ) except: pass try: duck = self.rsvpevent.total_rsvp return reverse( 'admin:events_rsvpevent_change', args=(self.id,) ) except: pass try: duck = self.listedevent.name return reverse( 'admin:events_listedevent_change', args=(self.id,) ) except: pass </code></pre> <p>There has to be a simpler, more easy-to-maintain method of finding out which type of event I'm looking at. Any ideas?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload