Merhabalar, bu yazıda Django Rest Framework ile veritabanında bir nesneyi oluşturma yada güncelleme sırasında save metoduna ekstra argüman geçme konusuna göz atacağız.
Öncelikle daha öncesinde Django model formlar ile nesne oluşturmuş yada güncellemiş iseniz aşağıdaki yapı tanıdık gelecektir;
class CreateInstanceView(LoginRequiredMixin, CreateView): form_class = YourModelForm success_url = reverse_lazy("your_success_url") template_name = "create_instance.html" def form_valid(self, form): self.object = form.save(commit=False) self.object.user = self.request.user self.object.save() return HttpResponseRedirect(self.get_success_url())
Bu yapı, veritabanında bulunması gereken fakat bilginin doğrudan son kullanıcıdan alınmadan (veritabanı ve orm yapısı gereği ilişkilendirilecek nesneyi), manuel işlem yaparak, içeriye almamıza olanak sağlamakta.
Kullanıcının ilişkilendirilmesi yaygın ve iyi bir örnek. Yazının devamında bu işlemin nasıl yapılabileceğine bir kaç farklı yol üzerinden göz atacağız.
Basit bir Todo modeli oluşturduğumuzu varsayalım;
# your_app/models.py from django.db import models class Todo(models.Model): user = models.ForeignKey("auth.User", on_delete=models.CASCADE) title = models.CharField(max_length=255) created_at = models.DateTimeField(auto_now_add=True) modified_at = models.DateTimeField(auto_now=True)
Daha sonrasında bir serializer sınıfı tanımlayalım;
class TodoSerializer(serializers.ModelSerializer): class Meta: model = Todo fields = "__all__" extra_kwargs = { "user" : { "required" : False } }
Serializer save metodu ile ekstra argüman geçmek.
APIView kullanımı.
from rest_framework.views import APIView from rest_framework import permissions, status from rest_framework.response import Response class TodoApiView(APIView): serializer_class = TodoSerializer permission_classes = (permissions.IsAuthenticated,) def post(self, request, *args, **kwargs): serializer = self.serializer_class( data=request.data, context={"request": request} ) serializer.is_valid(raise_exception=True) serializer.save(user=request.user) return Response(serializer.data, status=status.HTTP_201_CREATED)
ModelSerializer’in save metodu, serializer üstünde bulunan validated_data ile birlikte, dışarıdan gelen kwargsları birleştirerek serializerin create metoduna geçirir, create metodu varsayılan model manager ile nesneyi oluşturur.
Dolayısıyla, serializerin save metodunu çağıracagınız anda ekstra argümanları model managera aktarılması için aşağıdaki şekilde belirtebilirsiniz.
serializer.save(user=request.user, field_1="field_1", field_2="field_2")
Generics ve Viewsetler içerisinde kullanım.
Generic viewlar ve viewsetler, DRF’in yüksek abstraction sağladığı, varsayılan basit CRUD işlemleri için çok kullanışlı araçlar.
Bu kullanışlılık, Python’ın güçlü OOP yaklaşımı ve rest_framework.mixins altındaki mixinler üzerine kurulu.
Mixinler varsayılan işlemlerini (oluşturma, güncelleme, silme) yaparken, custom davranışlar için bir hook mekanizmasına sahiptir. Örneğin, kayıt edilen kullanıcıya mail atma, validasyon yada serializera ekstra veri paslamak.
class CreateTodoView(generics.CreateAPIView): serializer_class = TodoSerializer def perform_create(self, serializer): serializer.save(user=self.request.user)
def perform_update(self, serializer): serializer.save(user=self.request.user, field_1="field_1", field_2="field2")
perform_create, perform_update icerisinde ekstra veriyi serializerın save metoduna geçirebilirsiniz.
CurrentUserDefault.
Eğer sadece, bir kullanıcı ile eşleştirme yapacaksanız DRF içerisinde bulunan CurrentUserDefault sınıfıda bir seçenek.
İlgili kullanıcı fieldini HiddenField olarak tanımlayıp, varsayılan değer olarak CurrentUserDefault geçmeniz durumunda context üstünde taşınan request nesnesinden kullanıcıyı geriye döndürecektir.
Örneğin;
class TodoSerializer(serializers.ModelSerializer): user = serializers.HiddenField(default=serializers.CurrentUserDefault()) class Meta: model = Todo fields = "__all__"
HiddenField sadece yazma işlemi için kullanılır ve safe isteklerde, nesnelerin serialize edilen verisine dahil edilmez. Okuma-yazma için ayrı serializerlar kullanıyorsanız bir problem yok. 🙂
Gün içinde takım arkadaşlarımdan, mail vs üzerinden gelen ve cevapladığım soruları artık kısa kısa olsada olsa kayıtlı kalması için blog haline getireceğim ve ilk yazısıda bu konu olmuş oldu. Umarım keyifli bir yazı olmuştur.
Görüşmek üzere!
İlk Yorumu Siz Yapın