Open4

DRFでthlogのバックエンドを制作するとき発生したエラーと解決まとめ

ピン留めされたアイテム
sh0sh0

このスクラップではzennのスクラップを韓国化したウェブプロジェクトであるthlogを制作しながら出てきた問題と解決策を掲示します。

ピン留めされたアイテム
sh0sh0

drf serializerでresponseする時method別に違う結果を返したい

-> serializerのto_representationをオーバーライドする。

class ThreadViewSerializer(ThreadSerializer):
    comments = CommentSerializer(read_only=True, many=True)

    def to_representation(self, instance):
        if self.context.get('request').method != 'GET':
            serializer = ThreadSerializer(instance, context={'request': self.context.get('request')})
            return serializer.data
        return super().to_representation(instance)

    class Meta:
        model = Thread
        fields = '__all__'

上記のコードでGET以外のmethodではcomments fieldを隠したかったのでto_representationをoverrideして解決

sh0sh0

django-taggitでターゲットobjectがcustom primary keyを使う時

django-taggitではobjectがカスタムしたpkを使う場合動かなくなる。(基本integer fieldにセットされている)
なのでItemBaseをカスタムしてfieldのthroughに指定する。

from taggit.models import CommonGenericTaggedItemBase, TaggedItemBase

# https://stackoverflow.com/questions/31683216/django-taggit-on-models-with-uuid-as-pk-throwing-out-of-range-on-save
# https://django-taggit.readthedocs.io/en/latest/custom_tagging.html
class CustomPkTaggedItemBase(CommonGenericTaggedItemBase, TaggedItemBase):
    object_id = models.CharField(max_length=60, verbose_name=_("object ID"), db_index=True)
class Thread(models.Model):
    id = models.CharField(primary_key=True, default=gen_pk, editable=False, max_length=60, db_index=True)
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='threads', db_index=True)
    folder = models.ForeignKey(Folder, on_delete=models.SET_NULL, null=True, default=None, related_name='threads')
    public = models.BooleanField(default=True)
    closed = models.BooleanField(default=False)
    title = models.CharField(max_length=100, null=False)
    topics = TaggableManager(through=CustomPkTaggedItemBase)
    created_at = models.DateTimeField(auto_now_add=True)
sh0sh0

django postgresql Gin Indexを適用

djangoでfulltext searchの性能を上げるためgin indexを使用。
https://blacksheephacks.pl/optimizing-django-database-queries-part-2/

makemigrations {appname} --empty コマンドでmigrationファイルを生成する。
生成したmigrationファイルのoperationsにTrigramとBtreeGinを追加する。

# Generated by Django 3.2.7 on 2021-10-03 10:37

from django.db import migrations
from django.contrib.postgres.operations import TrigramExtension, BtreeGinExtension


class Migration(migrations.Migration):

    dependencies = [
        ('thlog', '0006_alter_threadlike_thread'),
    ]

    operations = [
        TrigramExtension(),
        BtreeGinExtension(),
    ]

settings.pyのINSTALLED_APPSに'django.contrib.postgres'を追加する

その後Metaクラスをmodelに追加する。

    class Meta:
        indexes = [
            GinIndex(name='thlog_thread_title', fields=['title'], opclasses=['gin_trgm_ops'])
        ]