views.py
from . import models, serializers
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.views import APIView
class getSongData(APIView):
serializer_class=serializers.SongSerializer
def get(self, request, id, format=None):
serializer = serializers.SongSerializer(models.Song.objects.get(id=id))
file_loc = serializer.data['audio_file'] # go below to see the data
# read the mp3 file
return Response(file_data)
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('songs/audio/<int:id>', views.getSongData.as_view(), name='audio')
]
serializers.py
from rest_framework import serializers
from . import models
class SongSerializer(serializers.ModelSerializer):
class Meta:
model = models.Song
fields = '__all__'
models.py
from django.db import models
from datetime import datetime
class Song(models.Model):
title = models.CharField(max_length=64)
audio_file = models.FileField()
genre = models.CharField(max_length=64)
created_at = models.DateTimeField(default=datetime.utcnow)
The data
[
{
"id": 1,
"title": "Kubbi | Cascade",
"audio_file": "/media/Kubbi__Cascade.mp3",
"genre": "Instrumental",
"created_at": "2021-07-24T10:21:48Z"
}
]
When the user clicks on a song (lets say the song's id=1), a request gets sent to 'http://localhost:8000/api/songs/audio/1' then in views.py I extract the song's location via serializer.data['audio_file'] which is = "/media/Kubbi__Cascade.mp3", all i want to do is to read this audio file and send the data as a Response back to the frontend, I tried many solutions but they were throwing errors...
if you want to do it using pure django this would work
from django.http import FileResponse
class getSongData(APIView):
serializer_class=serializers.SongSerializer
def get(self, request, id, *args, **kwargs):
song = models.Song.objects.get(id=id)
return FileResponse(song.audio_file.open())
but preferably you should serve files through a reverse proxy for better performance.
Related
I am trying to make a crud API using Django rest_framework the get request seems to work fine
for me but the post request is not working at all when I try to print the request.data it gives an empty dictionary
Please help me to resolve this issue
views.py file
from rest_framework import serializers
from . models import freelancerJob
from django.http import JsonResponse
from .serializers import jobPostSerializer
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from rest_framework.status import HTTP_200_OK,HTTP_400_BAD_REQUEST
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.decorators import parser_classes
from rest_framework.parsers import JSONParser
from rest_framework import viewsets
#csrf_exempt
#api_view(['GET', 'POST','DELETE'])
#parser_classes([JSONParser])
def jobPostView(request,format=None):
if request.method == "POST":
print("data",request.data)
serializer = jobPostSerializer(data=request.data)
print(serializer.initial_data)
if serializer.is_valid(raise_exception=True):
serializer.save()
return JsonResponse({'data':serializer.data},status = HTTP_200_OK )
else:
return Response({'status':'error','data':serializer.data},status = HTTP_400_BAD_REQUEST)
if request.method == "GET":
data = freelancerJob.objects.all().order_by('id')
serializer = jobPostSerializer(data ,many = True)
return Response({"status":'success','data':serializer.data},status = HTTP_200_OK)
My serializers.py file
from rest_framework import serializers
from . models import freelancerJob
class jobPostSerializer(serializers.HyperlinkedModelSerializer):
def create(self,validated_data):
return freelancerJob.object.create(**validated_data)
class Meta:
model = freelancerJob
fields = ['title','description','skill','duration','budget','types']
my models.py file
from operator import truediv
from django.db import models
class freelancerJob(models.Model):
Job_duration = (
('1','Less than 1 month'),
('3','1 to 3 months'),
('6','3 to 6 month'),
('12','More than 6 months')
)
Job_type=(("Individual",'Individual freelancer'),
('Team','Team')
)
title = models.CharField(max_length=250,null=True,blank=False)
description = models.CharField(max_length=2000,blank=False)
skill= models.CharField(max_length=250)
duration = models.CharField(max_length=50 ,blank=False,choices=Job_duration)
budget = models.IntegerField(blank=False)
types = models.CharField(max_length=50,blank=False,choices=Job_type)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
When I try to print the request.data that is coming from the post request it gives an empty dictionary
I am using Django 3.0 djangorestframework==3.11.0. I have created a task update view and passing the pk to url. The problem is - Although I have set the serializer instance to the model object I want to update. The serializer instance is not showing up.
models.py
from django.db import models
# Create your models here.
class Task(models.Model):
title = models.CharField(max_length=200)
completed = models.BooleanField(default=False, blank=True, null=True)
def __str__(self):
return self.title
serializers.py
from rest_framework import serializers
from .models import Task
class TaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
fields = '__all__'
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.apiOverview, name='api-overview'),
path('task-list/', views.taskList, name='task-list'),
path('task-detail/<str:pk>/', views.taskDetail, name='task-detail'),
path('task-create/', views.taskCreate, name='task-create'),
path('task-update/<str:pk>/', views.taskUpdate, name='task-update'),
]
views.py
from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Task
from .serializers import TaskSerializer
#api_view(['POST'])
def taskUpdate(request, pk):
task = Task.objects.get(id=pk)
serializer = TaskSerializer(instance=task, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
expected behavior on url http://localhost:8000/api/task-update/4/
actual behaviour on http://localhost:8000/api/task-update/4/
as you can see the content field is empty but I want the already associated json to be shown there with pk = 4.
In fact, I need your help to limit my API to upload
I only need Jason and excel formats(csv,xls,xlsl) on the server-side, but I did not find any code for that.
The second question is, what methods should I use to authenticate the user?
Here's a link that I use its code in my API
in fact, I need fix this part:
from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from rest_framework.response import Response
from rest_framework import status
from .serializers import FileSerializer
class FileView(APIView):
parser_classes = (MultiPartParser, FormParser)
def post(self, request, *args, **kwargs):
file_serializer = FileSerializer(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
return Response(file_serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def get():
pass
def update():
pass
my model :
from django.db import models
class File(models.Model):
file = models.FileField(blank=False, null=False)
remark = models.CharField(max_length=20)
timestamp = models.DateTimeField(auto_now_add=True)
and my serializers :
from rest_framework import serializers
from .models import File
class FileSerializer(serializers.ModelSerializer):
class Meta():
model = File
fields = ('file', 'remark', 'timestamp')
but I didn't know how most make it limit
my Django version is 2 AND my python version is 3
I will thank you if you help me :)
have to go coding time
I got an error,
AttributeError at /app/api/get
Got AttributeError when attempting to get a value for field task_name on serializer TaskSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the Color instance.
Original exception text was: 'Color' object has no attribute 'task_name'.
Now I wanna make a page that shows model's content in json format.
models.py is
from django.db import models
# Create your models here.
class Color(models.Model):
name = models.CharField(max_length=255)
background_color = models.CharField(max_length=255)
h1_color = models.CharField(max_length=255)
p_color = models.CharField(max_length=255)
def __str__(self):
return self.name
serializers.py is
from .models import Color
from rest_framework import serializers
class TaskSerializer(serializers.Serializer):
task_name = serializers.CharField(max_length=100)
status = serializers.SerializerMethodField('get_task_status')
def get_task_status(self, instance):
return instance.status.status
class Meta:
model = Color
fields = ('name',
'background_color',
'h1_color',
'p_color',
'task_name')
urls.py is
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'api/get',views.TaskGet.as_view(),name='task-get')
]
views.py is
from django.shortcuts import render
from .models import Color
from .forms import ColorForm
from .serializers import TaskSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
# Create your views here.
def index(request):
d = {
'colors': Color.objects.all(),
'form': ColorForm(),
}
return render(request, 'index.html', d)
class TaskGet(APIView):
def get(self, request, format=None):
obj = Color.objects.all()
serializers = TaskSerializer(obj, many=True)
return Response(serializers.data, status.HTTP_200_OK)
I wrote url(r'api/get',views.TaskGet.as_view(),name='task-get') in urls.py,so I really cannot understand why this error happens.I already run commands of migration of model. How can I fix this?
My ideal web page is like
You try get status by foreign key instance.status.status but in your model class Color i don't see any foreign keys or methods for it.
And for task_name did you want to see the model field name try to add source params
task_name = serializers.CharField(max_length=100, source='name')
# ^^^^^^^^^
are you sure you want serialize Task for model Color?
new edit
in your get_task_status the 'instanceis instance of serializer model, so if your modelColorhas no property or methodstatus` you will catch an error
I started to code a two-apps django project. ModelA belongs to appone and ModelB belongs to apptwo. My purpose is to create a ModelA instance everytime that the user creates a ModelB instance. And the value of a ModelA CharField (that is ckeditor widgeted) must be the source code of a ModelB admin view. I used a post_data signal to link a function of creation for that. The problem is that i use the id of each instance of ModelB in order to create the good content for each instance of ModelA. When I try to use a string of the url sending the id parameter, the content field has for value the source code of the debug page
(error 500, DoesNotExist at /admin/apptwo/modelb/my_view/ref=76, [76 is an example] ModelB matching query does not exist. Exception location : /home/me/Desktop/env/lib/python3.5/site-packages/django/db/models/query.py in get, line 385)
But when I try to visit the url "http://localhost:8000//admin/apptwo/modelb/my_view/ref=76", or when I hardcode the url, without a str(instance.id), the page exists and everything works perfectly.
I don't understand why.
Could anybody give me some help to solve this problem ?
Thanks in advance,
PS :
The first app has a model.py that contains the following code :
from django.db import models
from django.contrib.auth.models import User
from registre.models import *
class ModelA(models.Model):
content = models.CharField(max_length=255, null=True)
def __str__(self):
return "ModelA : " + str(self.id)
the admin.py of this first app also contains :
from django.contrib import admin
from appone.models import *
from apptwo.models import ModelB
from django.http import HttpResponse
from django.template.response import TemplateResponse
from django.conf.urls import url
from registre import views
from django.db.models.signals import post_save
from django.dispatch import receiver
import datetime
from django.contrib.auth.models import User
from django import forms
from ckeditor.widgets import CKEditorWidget
from django.template.loader import render_to_string
import requests
class ModelAAdminForm(forms.ModelForm):
content = forms.CharField(widget=CKEditorWidget())
class Meta:
model = ModelA
fields = '__all__'
class ModelAAdmin(admin.ModelAdmin):
form = ModelAAdminForm
def create_A(sender, instance, **kwargs):
string = "http://localhost:8000/admin/apptwo/modelb/my_view/ref=" + str(instance.id)
r = requests.get(string)
ModelA.objects.create(contenu=r.text.encode('utf-8'))
post_save.connect(create_A, sender=ModelB)
admin.site.register(ModelA, ModelAAdmin)
the second app (apptwo) has a models.py like this :
from django.db import models
from django.contrib.auth.models import User
class ModelB(models.Model):
owner = models.ForeignKey(User, null=True)
name = models.CharField(max_length=255, null=True)
def __str__(self):
return self.name
and an admin.py that contains :
from django.contrib import admin
from appone.models import *
from apptwo.models import *
import datetime
from django.conf.urls import url, include
from django.template.response import TemplateResponse
class ModelBAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super(ModelB, self).get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(owner=request.user)
def save_model(self, request, obj, form, change):
obj.owner = request.user
obj.save()
def get_urls(self):
urls = super(ModelBAdmin, self).get_urls()
my_urls = [
url(r'^my_view/ref=(?P<id>\d+)$', self.my_view),
]
return my_urls + urls
def my_view(self, request, id):
context = dict(
self.admin_site.each_context(request),
selector = ModelB.objects.get(id=id),
)
return TemplateResponse(request, "myview.html", context)
admin.site.register(ModelB, ModelBAdmin)
and finally a template myview.html with :
<p>Test {{ selector.name }}</p>