15

私のコードにはこのモデルがあります:

class Conversation(models.Model):
    participants = models.ManyToManyField(User, related_name="message_participants")

そして、この「会話」モデルオブジェクトを「参加者」の多対多フィールドでフィルタリングする必要があります。意味:たとえば、3つのユーザーオブジェクトがあるので、「参加者」フィールドにこの3つのユーザーが含まれる「会話」オブジェクトのみを取得したいと思います。

私はこれをやってみました:

def get_exist_conv_or_none(sender,recipients):
    conv = Conversation.objects.filter(participants=sender)
    for rec in recipients:
        conv = conv.filter(participants=rec)

ここで、senderはUserオブジェクトであり、「recipients」はUserオブジェクトのリストです。エラーは発生しませんが、間違った会話オブジェクトが表示されます。ありがとう。

編集:最近の試みは私をこれに導きます:

def get_exist_conv_or_none(sender,recipients):
    participants=recipients
    participants.append(sender)
    conv = Conversation.objects.filter(participants__in=participants)
    return conv

基本的に同じ問題があります。これにより、リストに1つ以上の「参加者」が含まれるオブジェクトが生成されます。しかし、Imが探しているのは、多対多のオブジェクトの完全一致です。つまり、正確な「ユーザー」が多対多の関係にあるオブジェクトです。

編集2:私の最後の試み。それでも、動作しません。

def get_exist_conv_or_none(sender,recipients):
    recipients.append(sender)
    recipients = list(set(recipients))
    conv = Conversation.objects.annotate(count=Count('participants')).filter(participants=recipients[0])
    for participant in recipients[1:]:
        conv.filter(participants=participant)
    conv.filter(count=len(recipients))
    return conv
4

2 に答える 2

10

わかりました。答えを見つけました。完全に一致させるには、モデルをチェーンフィルタリングしてから、必要な引数の数が正確に含まれていることを確認する必要があります。これにより、多対多のフィールドにそれは必要なすべてのオブジェクトであり、それ以上ではありません。

アノテーションを使用してオブジェクト番号を確認します:(https://docs.djangoproject.com/en/dev/topics/db/aggregation/

このコードで終わった:

def get_exist_conv_or_none(recipients):
    conv = Conversation.objects.annotate(count=Count('participants')).filter(participants=recipients[0])
    for participant in recipients[1:]:
        conv = conv.filter(participants=participant)
    conv = conv.filter(count=len(recipients))
    return conv
于 2012-11-27T17:26:32.167 に答える
3

データベースインデックスを使用した高速検索には、次のコードを使用します。

class YandexWordstatQueue(models.Model):
    regions = models.ManyToManyField(YandexRegion)
    regions_cached = models.CharField(max_length=10000, editable=False, db_index=True)
    phrase = models.ForeignKey(SearchPhrase, db_index=True)
    tstamp = models.DateTimeField(auto_now_add=True)

class YandexWordstatRecord(models.Model):
    regions = models.ManyToManyField(YandexRegion)
    regions_cached = models.CharField(max_length=10000, editable=False, db_index=True)
    phrase = models.ForeignKey(SearchPhrase, db_index=True)
    Shows = models.IntegerField()
    date = models.DateField(auto_now_add=True)

@receiver(m2m_changed, sender=YandexWordstatRecord.regions.through)
@receiver(m2m_changed, sender=YandexWordstatQueue.regions.through)
def yandexwordstat_regions_changed(sender, **kwargs):
    if kwargs.get('action') in ['post_add', 'post_remove']:
        instance = kwargs.get('instance')
        l = list(instance.regions.values_list('RegionID', flat=True))
        l.sort()
        instance.regions_cached = json.dumps(l)
        instance.save()

これにより、保存時にオーバーヘッドが追加されますが、このスニペットを使用して高速フィルターを実行できるようになりました。

region_ids = [1, 2, 3] # or list(some_queryset.values_list(...))
region_ids.sort()
regions_cahed = json.dumps(region_ids)
YandexWordstatQueue.objects.filter(regions_cached=regions_cached)
于 2013-01-13T13:56:12.863 に答える