Belajar Django: DRF ListCreateAPIView Custom Queryset & Post

Masih lanjut yang terkait ListCreateAPIView, pada kode yang kemarin saya hanya mendeklarasikan saja beberapa hal di views dan secara ajaib semua sudah berjalan, contoh dalam kode, saya hanya mendeklarasikan queryset yang digunakan adalah dari model Post, dan di sana saya mengambil semuanya tanpa terkecuali. Lalu bagiamana jika kita ingin mengambil post yang publish-nya bernilai True dan dibuat lebih dari kemarin misalnya, yang jauh-jauh hari gak perlu dimunculin. Caranya mudah, kita cukup membuat method “get_queryset()” di dalam class dan ubah kode jadi berikut

from rest_framework.generics import ListCreateAPIView
from .models import Post, Category
from .serializers import PostSerializer
from rest_framework import filters
from .pagination import MyPagination
from datetime import datetime, timedelta

class PostListCreate(ListCreateAPIView):
    serializer_class = PostSerializer
    filter_backends = (filters.SearchFilter,)
    search_fields = ('title', 'content')
    pagination_class = MyPagination

    def get_queryset(self):
      yesterday = datetime.now() - timedelta(1)
      return Post.objects.filter(publish=True, created_at__gt=yesterday)

Dengan kode di atas saya membuat mengganti atribut queryset dengan method get_queryset(), dan hasilnya saat kita coba akses list

{
  "status": 200,
  "message": "Success",
  "links": {
    "next": null,
    "previous": null,
    "total_page": 1
  },
  "total": 2,
  "total_on_page": "2 from 2",
  "data": [
    {
      "id": 5,
      "title": "Something 3",
      "content": "modelss",
      "publish": true,
      "created_at": "2019-07-23T15:55:29.197989Z",
      "updated_at": "2019-07-23T15:55:29.198038Z",
      "category_id": {
        "id": 1,
        "title": "Cat 1"
      }
    },
    {
      "id": 6,
      "title": "Something 4",
      "content": "modelss",
      "publish": true,
      "created_at": "2019-07-23T15:55:45.226811Z",
      "updated_at": "2019-07-23T15:55:45.226858Z",
      "category_id": {
        "id": 1,
        "title": "Cat 1"
      }
    }
  ]
}

Manipulasi POST

Misalkan dalam model Post saya ingin menambahkan nilai slug jadi kalau ada judul “Belum Ada Judul” akan memiliki slug “belum-ada-judul”, tapi karena saat ini belum ada slug di model mari kita tambahkan dimunculin
Ubah model Post menjadi seperti berikut

class Post(models.Model):
    category_id=models.ForeignKey(Category, on_delete=models.CASCADE)
    title=models.CharField(max_length=200)
    slug=models.CharField(max_length=200, null=True, blank=True)
    content=models.TextField()
    publish=models.BooleanField(default=False)
    created_at=models.DateTimeField(auto_now_add=True)
    updated_at=models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

Buat migration dan migrate

python manage.py makemigrations

python manage.py migrate

Jika berhasil kolom slug sudah ditambahkan di table.

Lalu untuk manipulasi post ubah views menjadi alias menambahkan method post()

from rest_framework.generics import ListCreateAPIView
from .models import Post, Category
from .serializers import PostSerializer
from rest_framework import filters
from .pagination import MyPagination
from datetime import datetime, timedelta

class PostListCreate(ListCreateAPIView):
    serializer_class = PostSerializer
    filter_backends = (filters.SearchFilter,)
    search_fields = ('title', 'content')
    pagination_class = MyPagination

    def get_queryset(self):
      yesterday = datetime.now() - timedelta(1)
      return Post.objects.filter(publish=True, created_at__gt=yesterday)
    
    def post(self, request, *args, **kwargs):
      if 'title' in request.data:
        title = request.data['title']
        request.data['slug'] = title.replace(' ','-')
      return self.create(request, *args, **kwargs)

Hasilnya

{
  "id": 7,
  "title": "Belum Ada Judul",
  "slug": "Belum-Ada-Judul",
  "content": "Belum ada content",
  "publish": true,
  "created_at": "2019-07-25T17:21:32.563235Z",
  "updated_at": "2019-07-25T17:21:32.563335Z",
  "category_id": {
    "id": 1,
    "title": "Cat 1"
  }
}

 

Note:
Jika post dilakukan dari content-type form-data, request.data di method POST imutable alias tidak bisa diapa-apain lagi, kalau content-type nya JSON maka request.data mutable.

Referensi: https://www.django-rest-framework.org/api-guide/generic-views/

Show Comments