50

GenericForeignKey を使用するのは初めてで、クエリ ステートメントで機能させることができませんでした。表はおおよそ次のようなものです。

class Ticket(models.Model):
    issue_ct = models.ForeignKey(ContentType, related_name='issue_content_type')
    issue_id = models.PositiveIntegerField(null=True, blank=True)
    issue = generic.GenericForeignKey('issue_ct', 'issue_id')

class Issue(models.Model):
    scan = models.ForeignKey(Scan)

スキャンは 1 つの問題を作成し、問題はいくつかのチケットを生成し、チケット テーブルへの外部キーとして問題を作成しました。Scan オブジェクトができたので、このスキャンに関連するすべてのチケットを照会したいと考えています。私はこれを最初に試しました:

tickets = Tickets.objects.filter(issue__scan=scan_obj)

これは機能しません。それから私はこれを試しました:

issue = Issue.objects.get(scan=scan_obj)
content_type = ContentType.objects.get_for_model(Issue)
tickets = Tickets.objects.filter(content_type=content_type, issue=issue)

それでもうまくいきません。django でこれらの種類のクエリを実行する方法を知る必要がありますか? ありがとう。

4

2 に答える 2

71

定義したフィールドは、インスタンスからアタッチされているTicket.issueに移動するのに役立ちますが、逆方向には移動できません。2 番目の例に近づいていますが、フィールドを使用する必要があります。クエリを実行することはできません(インスタンスがある場合にオブジェクトを取得するのに役立ちます)。これを試して:TicketIssueissue_idGenericForeignKeyTicket

from django.contrib.contenttypes.models import ContentType

issue = Issue.objects.get(scan=scan_obj)
tickets = Ticket.objects.filter(
    issue_id=issue.id,
    issue_ct=ContentType.objects.get_for_model(issue).id
    )
于 2012-08-14T20:48:59.700 に答える
15

GenericForeignKeyと共有する 2 番目のモデルを作成して、缶全体をフィルタリングdb_tableTicketます。まず、チケットを抽象モデルと具象モデルに分割します。

class TicketBase(models.Model):
    issue_ct = models.ForeignKey(ContentType, related_name='issue_content_type')
    issue_id = models.PositiveIntegerField(null=True, blank=True)

    class Meta:
        abstract = True

class Ticket(TicketBase):
    issue = generic.GenericForeignKey('issue_ct', 'issue_id')

次に、 もサブクラス化するモデルを作成しますTicketBaseissueこのサブクラスには、代わりに として定義されているものを除いて、すべて同じフィールドがありForeignKeyます。カスタムを追加するManagerと、単一のContentType.

このサブクラスは同期または移行する必要がないため、 を使用して動的に作成できますtype()

def subclass_for_content_type(content_type):
    class Meta:
        db_table = Ticket._meta.db_table

    class Manager(models.Manager):
        """ constrain queries to a single content type """
        def get_query_set(self):
            return super(Manager, self).get_query_set().filter(issue_ct=content_type)

    attrs = {
        'related_to': models.ForeignKey(content_type.model_class()),
        '__module__': 'myapp.models',
        'Meta': Meta,
        'objects': Manager()
    }
   return type("Ticket_%s" % content_type.name, (TicketBase,), attrs)
于 2014-01-10T16:00:58.850 に答える