私はチャネル/ポストメカニズムを含むプロジェクトに取り組んでいます。私は現在、削除された時のタイムスタンプに "deleted"という名前のフィールドを設定することによって、投稿を "削除"する機能を実装しています。歴史的意義(最後の活動)と炎症を起こしている人々(このサービスはプロジェクト全体の特権に基づく部分)を追跡する必要があります。Django ORM関連オブジェクトをフィールド値でフィルタリングしますか?
models.py
class Post(models.Model):
deleted = models.DateTimeField(null=True, blank=True)
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now_add=True)
post_text = models.CharField(max_length=1000)
post_to = models.ForeignKey('Channel', related_name='post_to_channel')
post_from = models.ForeignKey(User, related_name='user_from_post')
class Channel(models.Model):
created_date = models.DateTimeField(auto_now_add=True)
channel_title = models.CharField(max_length=50, unique=True)
channel_description = models.CharField(max_length=100)
channel_creator = models.ForeignKey(User)
channel_private = models.BooleanField(default=False)
channel_users = models.ManyToManyField(User, through='Membership', related_name='channels', blank=True)
channel_posts = models.ManyToManyField(Post, related_name='channel_post', blank=True)
initial_invites = models.ForeignKey(User, null=True, blank=True, related_name='initial_invites')
objects = models.Manager()
class Membership(models.Model):
channel = models.ForeignKey(Channel)
channel_user = models.ForeignKey(User, related_name='channel_membership')
join_date = models.DateTimeField(auto_now_add=True)
私はヌルからのタイムスタンプであることを「ポスト」オブジェクトの「削除」フィールドを更新したエンドポイントを持っています。どのようにして、「チャネル」レベルで照会されたときにタイムスタンプを持つすべての投稿が返されるのを避けることができます。基本的には、私は "チャンネル"を照会し、私がその一部であるチャンネルのリストを取得し、ManyToManyと "Post"との関係を通して、 "deleted"フィールドに値を持つものを除くすべての関連Postをロードする必要があります。これは、各チャンネルのORMを呼び出すことなく可能ですか?その後、削除された投稿をフィルタリングしますか?明らかにするには、削除された投稿がある場合は「チャンネル」が引き続き表示されますが、「投稿」自体のみを非表示にする必要があります。
私は十分な情報を提供していない場合は、あなたが見たいものを教えてください。
回答がORM呼び出しを繰り返すことなしには不可能である場合は、これらの状況で呼び出されるフックを使わずに、複製モデルへの投稿を「アーカイブ」するオプションの重み付けなど、オリジナルを削除します。
編集1: 選ばれた解答に述べたようにプロパティを追加し、しかし、それはself.channel_posts
を見ることはできません。 models.py
class Channel(models.Model):
created_date = models.DateTimeField(auto_now_add=True)
channel_title = models.CharField(max_length=50, unique=True)
channel_description = models.CharField(max_length=100)
channel_creator = models.ForeignKey(User)
channel_private = models.BooleanField(default=False)
channel_users = models.ManyToManyField(User, through='Membership', related_name='channels', blank=True)
channel_posts = models.ManyToManyField(Post, related_name='channel_post', blank=True)
initial_invites = models.ForeignKey(User, null=True, blank=True, related_name='initial_invites')
objects = models.Manager()
@property
def get_viewable_posts(self):
print (self.channel_users) # prints []
print (self.channel_posts) # prints []
return CourtyardPost.objects.filter(deleted__isnull=True, courtyard_post_to=self.pk) #works, but adds IO strain
は現在、上に示したように、チャネルあたりのORMコールだが、self.channel_posts
またはself.channel_users
を印刷すると、すべてのシナリオでは、空のリストを返します。下記実施されるようなプロパティはDjangoの残りFrameworkのシリアライザの一部として呼び出されます。
class CourtyardChannelSerializer(serializers.ModelSerializer):
current_user = serializers.SerializerMethodField('_user')
post_to_channel = CourtyardPostSerializer(many=True, source='get_viewable_posts', read_only=True)
most_recent = CourtyardPostSerializer(many=True, source='latest_post', read_only=True)
channel_users = CourtyardUserSerializer(many=True, read_only=True)
)
invite_list = serializers.ReadOnlyField(source='get_invitation_set', required=False)
def _user(self, obj):
user = self.context['request'].user.username
return user
ようにそれを使用することができます.channel_posts'はプロパティのポイントで(印刷を介して)フィルタリングされているかどうかにかかわらず、空の配列です。私はそれをすべての投稿のフィルタ付きクエリーセットに書き直す必要がありましたが、これは大規模に(多くのDB呼び出しのために)うまく動作しません。あなたは答えがまだきれいです、ちょうどあなたが私の一時的なバージョンの代わりにそれを書いたように動作することを望んでいる。いずれにせよ、あなたの助けと時間をありがとう! – AntonMiles
コードを正確に実行すると、明らかにDBの "最初の"チャンネルのactive_postsが得られます。 Channel.objects.first()はDB内の最初のチャンネルを返してから です。 最初のチャンネルに投稿がないことはありますか? – Ramast
シリアライザのManyToMany関係の表現のソースとして 'active_posts'を使用できるようにしましたが、これを説明するために質問を編集しますが、デフォルトのユーザのチャンネルには何も表示されません。削除機能を開始する前に利用可能なポストを所持していたユーザー、その後ポストしたユーザー(別のエンドポイントを介して表示され、動作します)。それは依然として最良の答えです。そして、クエリーセットのためにそれを交換することは、DB IOの歪みを減らすことを望んでいます。 *明確にするために編集されています。 – AntonMiles