0

メインEventクラスと 4 つのイベント タイプがあります。それらのそれぞれは (少なくとも) のサブクラスですEvent。イベントの詳細ページに、特定のイベントの管理インターフェイスに戻るリンクを追加して、管理画面で検索する時間を節約しています。残念ながら、子クラスに関係なく、イベントは親Eventクラスから選択されます。この問題に対する私の解決策は、タイプをアヒルにすることでした。私の問題に対して、よりエレガントで保守しやすい解決策があることを願っています。

モデル:

class Event(models.Model):
    ...

class ListedEvent(Event):
    ....

class RSVPEvent(Event):
    ....

class TicketedEvent(Event):
    ....

class TicketedConcert(TicketedEvent):
    ....

イベントの詳細を表示するには、URL で会場スラッグとイベント名スラッグを渡します。Eventこれは、すべての子イベントにわたって親モデルから 1 つのイベントを分離するのに十分な情報です。また、イベントの種類を URL から除外して、よりシンプルで使いやすいものにできます。

@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}

戻って親Eventモデルを使用していることに気付く前は、このソリューションははるかに洗練されており、実際のモデル (親クラスのプロパティEvent)からイベントを選択すると仮定すると、シェルで正常に機能しました。

@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,))

私の現在の解決策(親クラスのプロパティEvent):

@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

私が見ているイベントのタイプを見つけるための、よりシンプルで維持しやすい方法が必要です。何か案は?

4

1 に答える 1

2

これは一般 的な 問題であり、依然として Django の醜いアヒルの子の 1 つです。

少なくとも 2 セントの DRY ゲインを得るために並べ替えることができます。

from django.core.exceptions import ObjectDoesNotExist

@property
def event_type(self):
     for et in ('ticketedevent', 'rsvpevent', 'sillyhatsonlyevent', ...):
         try:
             getattr(self, et)
             return et
         except ObjectDoesNotExist:
             pass

@property
def admin_link(self):
    return reverse('admin:events_%s_change' % self.event_type, args=(self.id,))

本当に凝りたい場合はEvent.__subclasses__、イベント タイプのリストを使用して生成できます。

于 2012-10-26T13:37:06.360 に答える