Django rest framework "Like" functionality - django

in django, I want to write a function that deletes the likes if the current user has liked that post before and if so, how can I do this.
This is my models.py
class Like(models.Model):
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
def __str__(self):
return self.created_by.username
This is my serializers.py
class LikeSerializer(serializers.ModelSerializer):
created_by = serializers.StringRelatedField()
post = serializers.StringRelatedField()
post_id = serializers.IntegerField()
class Meta:
model = Like
fields = ('__all__')
This is my views.py
class LikesView(viewsets.ModelViewSet):
queryset = Like.objects.all()
serializer_class = LikeSerializer
def perform_create(self, serializer):
serializer.save(created_by=self.request.user)
This is my urls.py
from django.urls import path,include
from .views import (
PostView,
PostView_View,
LikesView,
CommentView
)
from rest_framework import routers
router = routers.DefaultRouter()
router.register('likes', LikesView)
router.register('post', PostView)
router.register('comment', CommentView)
urlpatterns = [
] + router.urls
I try that but still nor working
class LikeSerializer(serializers.ModelSerializer):
created_by = serializers.StringRelatedField()
post = serializers.StringRelatedField()
post_id = serializers.IntegerField()
class Meta:
model = Like
fields = ('__all__')
def post(self, request, post_id):
post = Post.objects.get(pk=post_id)
if Like.objects.filter(post=post,
created_by=request.user).exists():
Like.objects.filter(post=post, created_by=request.user).delete()
else:
Like.objects.create(post=post, created_by=request.user)

For this action, you can override the serializer's save method. First, get an object from a table, and if it exists, delete it
https://www.django-rest-framework.org/api-guide/serializers/

Related

List of objects return empty - using django - mixins, generic views

views.py
class ReviewList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = Review.objects.all()
serializer_class = ReviewSerializer
def get(self,request,*args,**kwargs):
return self.list(request, *args, **kwargs)
def post(self,request,*args,**kwargs):
return self.create(request, *args, **kwargs)
models.py
class Review(models.Model):
rating = models.PositiveIntegerField(validators=[MinValueValidator(1),MaxValueValidator(5)])
description = models.CharField(max_length=200, null=True)
created = models.DateTimeField(auto_now_add=True)
update = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
watchlist = models.ForeignKey(WatchList, on_delete=models.CASCADE, related_name='reviews')
def __str__(self) -> str:
return str(self.rating) + ' - ' + self.watchlist.title
urls.py
urlpatterns = [
path('list/', WatchListAV.as_view(), name='movie-list'),
path('<int:pk>', MovieDetailsAV.as_view(),name='movie-details'),
path('stream/',StreamPlatformAV.as_view(),name='stream-list'),
path('stream/<int:pk>', StreamDetailAV.as_view(), name="stream-detail"),
path('review/', ReviewList.as_view(),name='review-list'),
]
serializers.py
class ReviewSerializer(serializers.Serializer):
class Meta:
model = Review
fields = '__all__'
the list of reviews return empty
as attached in photo the list of reviews is empty, im new to django cant figure it out
When creating serializers for a model you should subclass ModelSerializer
class ReviewSerializer(serializers.ModelSerializer):
class Meta:
model = Review
fields = '__all__'

Django | Filter Ordering - How to implement "ordering" when you use #property

please help me to make the correct "ordering" for a "custom" property some_property_field. I write such an URL and it doesn't work. I understand the reason is a "custom" property. How to work it out?
/api/articles/?ordering=-some_property_field
urls.py
router = DefaultRouter()
router.register(r'articles', ArticleViewSet, basename='articles')
urlpatterns = []
urlpatterns += router.urls
models.py
class Article(models.Model):
title = models.CharField(max_length=20)
description = models.TextField()
def __str__(self):
return self.title
#property
def some_property_field(self):
return f'{self.title} property func'
views.py
class ArticleViewSet(viewsets.ModelViewSet):
serializer_class = ArticleSerializer
queryset = Article.objects.all()
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter,)
ordering_fields = ('id', 'title', 'some_property_field')
ordering = ('id',) # default ordering
serializers.py
class ArticleSerializer(serializers.ModelSerializer):
some_property_field = serializers.CharField(read_only=True)
class Meta:
model = Article
fields = '__all__'
Ordering is done in queryset so you can only use field that exists in database.
If you want to order by property you need to do that in python:
qs = sorted(Article.objects.all(), key=lambda obj: obj.some_property_field)

How to set items to a specific Todolist in Django Rest Framework?

Im building a TODO app using django rest framework. I have to two models namely todolist and todoitem.How can I set a new todoitem to a specific todolist? I tried using foreign key but it didn't worked out,Sorry for my bad english,Can anyone please help me
My models.py:
class todolist(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE,default=None)
name = models.CharField(max_length=128)
creation_date = models.DateField(auto_now=True)
def __unicode__(self):
return self.name
class todoitem(models.Model):
description = models.CharField(max_length=150)
completed = models.BooleanField(default=False)
due_by = models.DateField(auto_now=True)
parent = models.ForeignKey(todolist,on_delete=models.CASCADE)
def _unicode__(self):
return self.description
My classviews.py:
class Todolist(LoginRequiredMixin,ListCreateAPIView):
serializer_class = listserializer
def perform_create(self, serializer):
serializer.save(user=self.request.user)
def get_queryset(self):
self.queryset = todolist.objects.filter(user=self.request.user)
return super(Todolist, self).get_queryset()
class Todolistdetail(LoginRequiredMixin,RetrieveUpdateDestroyAPIView):
def get_queryset(self):
self.queryset = todolist.objects.filter(user=self.request.user)
return super(Todolistdetail, self).get_queryset()
serializer_class = listserializer
class Todoitem(LoginRequiredMixin,ListCreateAPIView):
def perform_create(self, serializer):
temp = self.queryset(todolist.objects.filter(id=self.kwargs['pk']))
serializer.save(parent=temp)
def get_queryset(self):
temp = todolist.objects.filter(id=self.kwargs['pk'])
self.queryset = todoitem.objects.filter(parent=temp)
return super(Todoitem, self).get_queryset()
serializer_class = itemserializer
class Todoitemdetail(LoginRequiredMixin,RetrieveUpdateDestroyAPIView):
def get_queryset(self):
temp = todolist.objects.filter(id=self.kwargs['list_id'])
self.queryset = todoitem.objects.filter(parent=temp)
return super(Todoitemdetail, self).get_queryset()
serializer_class = itemserializer
My serializers.py:
class listserializer(serializers.ModelSerializer):
user = serializers.ReadOnlyField(source='user.username')
class Meta:
model = todolist
fields = '__all__'
class itemserializer(serializers.ModelSerializer):
parent = serializers.ReadOnlyField(source='todolist.id')
class Meta:
model = todoitem
fields = '__all__'
My urls.py:
from todoapp import classviews
app_name = "todoapp"
urlpatterns = [
url(r'^list/$',classviews.Todolist.as_view(),name="list_lists"),
url(r'^list/(?P<pk>[0-9]+)/$',classviews.Todolistdetail.as_view(),name="each_list"),
url(r'^list/(?P<pk>[0-9]+)/item/$',classviews.Todoitem.as_view(),name="list_items"),
url(r'^list/(?P<list_id>[0-9]+)/item/(?P<pk>[0-9]+)/$',classviews.Todoitemdetail.as_view(),name="each_item")
]
view:
from rest_framework.viewsets import ModelViewSet
class TodoitemViewSet(ModelViewSet):
queryset = Todoitem.objects.all()
serializer_class = itemserializer
permission_classes = (IsAuthenticated)
serializer.py
class itemserializer(serializers.ModelSerializer):
class Meta:
model=todoitem
fields='__all__'
url:
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'todo_item', TodoitemViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include(router.urls)),
]
jsut post data {'parent':1 'description':'example',....} to www.example.com/todo_item/, parent is your todolist'id.

Django Rest Framework Post Nested Using Files with requests module example

Excuse me, i have a problem, can anyone help me.
I have models like:
from django.db import models
from django.contrib.auth.models import User
import uuid
def uuid_generator():
return str(uuid.uuid4())
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile_user')
mobile = models.CharField(max_length=20)
alamat = models.TextField(blank=True)
phone = models.CharField(max_length=20, blank=True)
foto = models.ImageField(upload_to='profile', blank=True)
def __str__(self):
return self.user.username
class Rumah(models.Model):
JENIS_CHOICES = (
('rumah', 'Rumah besar'),
('petakan', 'Rumah petakan'),
('apartement', 'Apartement'),
('kost', 'Kost-Kostan')
)
WAKTU_CHOICES = (
('bulanan', 'Bulanan'),
('tahunan', 'Tahunan'),
)
STATUS_CHOICES = (
('tersedia', 'Tersedia'),
('terisi', 'Sudah Terisi'),
('ditutup', 'Di Tutup'),
)
pemilik = models.ForeignKey(User, on_delete=models.CASCADE, related_name='rumah_user')
kode = models.CharField(unique=True, max_length=150)
jenis = models.CharField(max_length=12, choices=JENIS_CHOICES, default='rumah')
waktu = models.CharField(max_length=10, choices=WAKTU_CHOICES, default='bulanan')
harga = models.PositiveIntegerField()
alamat = models.TextField()
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='tersedia')
keterangan = models.TextField(blank=True)
def __str__(self):
return self.kode
def save(self, *args, **kwargs):
self.kode = uuid_generator()
super(Rumah, self).save(*args, **kwargs)
class Foto(models.Model):
rumah = models.ForeignKey(Rumah, on_delete=models.CASCADE, related_name='foto_rumah')
penampakan = models.ImageField(upload_to='penampakan', blank=True)
keterangan = models.TextField(blank=True)
def __str__(self):
return self.rumah.kode
Note: Rumah like House in english and Foto like Picture in english.
I have a views like:
from django.contrib.auth.models import User
from produk.models import Profile, Rumah, Foto
from .serializers import UserSerializer, ProfileSerializer, RumahSerializer, FotoSerializer
from .permissions import IsOwnerOrReadOnly, IsHasProfile, IsRumahOrReadOnly
from rest_framework import mixins
from rest_framework import generics
from rest_framework import permissions
class UserList(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetail(generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class ProfileList(generics.ListCreateAPIView):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def perform_create(self, serializer):
serializer.save(user=self.request.user)
class ProfileDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly)
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
class RumahList(generics.ListCreateAPIView):
queryset = Rumah.objects.all()
serializer_class = RumahSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def perform_create(self, serializer):
serializer.save(pemilik=self.request.user)
class RumahDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Rumah.objects.all()
serializer_class = RumahSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly)
class FotoList(generics.ListCreateAPIView):
queryset = Foto.objects.all()
serializer_class = FotoSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class FotoDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Foto.objects.all()
serializer_class = FotoSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsRumahOrReadOnly)
I have a serializers like:
from django.contrib.auth.models import User
from rest_framework import serializers
from produk.models import Profile, Rumah, Foto
class UserSerializer(serializers.HyperlinkedModelSerializer):
rumah_user = serializers.HyperlinkedRelatedField(many=True, view_name='rumah-detail', read_only=True)
profile_user = serializers.HyperlinkedRelatedField(many=False, view_name='profile-detail', read_only=True)
class Meta:
model = User
fields = ('id', 'username', 'email', 'is_active', 'rumah_user', 'profile_user')
class ProfileSerializer(serializers.ModelSerializer):
user = serializers.ReadOnlyField(source='user.username')
class Meta:
model = Profile
fields = ('id', 'user', 'alamat', 'mobile', 'phone', 'foto')
class FotoSerializer(serializers.ModelSerializer):
# rumah = serializers.ReadOnlyField(source='rumah.kode')
class Meta:
model = Foto
fields = ('id', 'rumah', 'penampakan', 'keterangan')
class RumahSerializer(serializers.ModelSerializer):
pemilik = serializers.ReadOnlyField(source='pemilik.username')
#foto_rumah = serializers.HyperlinkedRelatedField(many=True, view_name='foto-detail', read_only=True)
foto_rumah = FotoSerializer(many=True)
class Meta:
model = Rumah
fields = ('id', 'pemilik', 'jenis', 'waktu', 'harga', 'alamat', 'status', 'keterangan', 'foto_rumah')
def create(self, validated_data):
fotos_data = validated_data.pop('foto_rumah')
print(validated_data)
rumah = Rumah.objects.create(**validated_data)
for foto_data in fotos_data:
Foto.objects.create(rumah=rumah, **foto_data)
return rumah
When i try it with requests module like:
import requests
from requests.auth import HTTPBasicAuth
url = 'http://127.0.0.1:8000/rumah/'
files = {'penampakan': open('C:\\Users\\yanz\\Pictures\\Campuran\\test.png', 'rb')}
data = {
"pemilik": "admin",
"jenis": "rumah",
"waktu": "bulanan",
"harga": 3,
"alamat": "r",
"status": "tersedia",
"keterangan": "4",
"foto_rumah": [
{
"penampakan": files,
"keterangan": "a"
}
]
}
r = requests.post(url, data=data, files=files, auth=HTTPBasicAuth('admin', 'password123'))
print(r.text)
Result:
{"id":11,"pemilik":"admin","jenis":"rumah","waktu":"bulanan","harga":3,"alamat":"r","status":"tersedia","keterangan":"4","foto_rumah":[]}
Foto (foto_rumah) data from the model Foto is not saved. what's the solution ? How to post nested data with files?
Thanks...
Nested serializers don't work with form encoded data yet.
Uploading images only works with form encoded data out of the box.
I guess you'll need to upload images on a specific non nested entry point or use base64 encoded files within the JSON.
I remember I've seen a 3rd party about handling base64 files but can't find it again.

TypeError: __init__() got multiple values for keyword argument 'view_name'

I am using the Django Rest Framework, and I am not sure why I am getting this error.
models.py
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
followers = models.ManyToManyField('self', related_name='followees', symmetrical=False)
class Post(models.Model):
author = models.ForeignKey(User, related_name = 'posts')
title = models.CharField(max_length = 255)
body = models.TextField(blank = True, null = True)
class Photo(models.Model):
post = models.ForeignKey(Post, related_name = 'photos')
image = models.ImageField(upload_to = '%Y/%m/%d')
serializers.py
from rest_framework import serializers
from .models import *
class UserSerializer(serializers.ModelSerializer):
# Getting the list of posts made by particular users using the username.
posts = serializers.HyperlinkedIdentityField(
'posts',
view_name = 'userpost-list',
lookup_field = 'username'
)
class Meta:
model = User
fields = ('id', 'username', 'first_name', 'last_name', 'posts',)
class PostSerializer(serializers.ModelSerializer):
author = UserSerializer(required = False)
photos = serializers.HyperlinkedIdentityField(
'photos',
view_name = 'postphoto-list'
)
def get_validated_exclusions(self):
# Need to exclude 'author' since we'll add that later
# based off the request user
exclusions = super(PostSerializer, self).get_validated_exclusions()
return exclusions + ['author']
class Meta:
model = Post
class PhotoSerializer(serializers.ModelSerializer):
image = serializers.Field('image.url')
class Meta:
model = Photo
views.py
from rest_framework import generics, permissions
from .serializers import *
from .models import *
class UserList(generics.ListCreateAPIView):
model = User
serializer_class = UserSerializer
permission_classes = [
permissions.AllowAny # Publically available to anyone
]
class UserDetail(generics.RetrieveAPIView):
model = User
serializer_class = UserSerializer
lookup_field = 'username'
class PostList(generics.ListCreateAPIView):
model = Post
serializer_class = PostSerializer
permission_classes = [
permissions.AllowAny
]
class PostDetail(generics.RetrieveAPIView):
model = Post
serializer_class = PostSerializer
permission_classes = [
permissions.AllowAny
]
class UserPostList(generics.ListAPIView):
"""
Lists all the posts of a particular User.
"""
model = Post
serializer_class = PostSerializer
def get_queryset(self):
queryset = super(UserPostList, self).get_queryset()
return queryset.filter(author__username = self.kwargs.get('username'))
class PhotoList(generics.ListCreateAPIView):
model = Photo
serializer_class = PhotoSerializer
permission_classes = [
permissions.AllowAny
]
class PhotoDetail(generics.RetrieveAPIView):
model = Photo
serializer_class = PhotoSerializer
permission_classes = [
permissions.AllowAny
]
class PostPhotoList(generics.ListAPIView):
model = Photo
serializer_class = PhotoSerializer
def get_queryset(self):
queryset = super(PostPhotoList, self).get_queryset()
return queryset.filter(post__pk = self.kwargs.get('pk'))
urls.py in my app directory
from django.conf.urls import patterns, url, include
from .views import *
urlpatterns = [
# User URLs
url(r'^users/$', UserList.as_view(), name='user-list'),
url(r'^users/(?P<username>[0-9a-zA-Z_-]+)/$', UserDetail.as_view(), name='user-detail'),
url(r'^users/(?P<username>[0-9a-zA-Z_-]+)/posts/$', UserPostList.as_view(), name='userpost-list'),
# Post URLs
url(r'^posts/$', PostList.as_view(), name='post-list'),
url(r'^posts/(?P<pk>\d+)/$', PostDetail.as_view(), name='post-detail'),
url(r'^posts/(?P<pk>\d+)/photos/$', PostPhotoList.as_view(), name='postphoto-list'),
# Photo URLs
url(r'^photos/$', PhotoList.as_view(), name='photo-list'),
url(r'^photos/(?P<pk>\d+)/$', PhotoDetail.as_view(), name='photo-detail'),
]
When I try to run the check command on my terminal, or runserver, I get this error:
TypeError: init() got multiple values for keyword argument 'view_name'
What am I doing wrong exactly, and how can I fix this problem?
The first argument to HyperlinkedIdentityField is view_name. You're passing an extra initial argument, which seems to be the same as the field name; remove this argument.