Is there some equivalent to {% url 'some-name' %} for router.register(...) - django

I am trying to get the URL to a specific ViewSet automatically.
I tried using {% url 'api-movement' %} but get the following error:
Reverse for 'api-movement' not found. 'api-movement' is not a valid view function or pattern name.
I searched the web but couldn't really find what I was looking for.
viewset.py
class MovementViewSet(viewsets.ModelViewSet):
queryset = Movement.objects.all()
serializer_class = MovementSerializer
router.py
from farm.api.viewsets import *
from rest_framework import routers
router = routers.DefaultRouter()
router.register('movement', MovementViewSet, base_name='api-movement')
urls.py
from django.urls import path, include
from farm.api.responder import *
from farm import views
from farm.router import router
urlpatterns = [
path('api/', include(router.urls)),
]
html excerpt:
$.ajaxSetup({
headers: { "X-CSRFToken": '{{csrf_token}}' },
});
$.ajax({
method: 'POST',
url: "{% url 'api-movement' %}",
data: {pk: pk},
success: function (data) {
location.reload();
},
error: function (error_data) {
alert('An error occurred, please reload page and try again.\n\nError: ' + error_data.responseText);
}
});

Related

django csrf issue with uploading image through Editor.js

I'm following django-editorjs(django package) tutorial of https://medium.com/analytics-vidhya/integrating-editorjs-with-django-7a30127d0771.
Whenever I try to upload image, I get this csrf error: Forbidden (CSRF token missing or incorrect.): /media/imageUpload/
I set up media root and url and I am able to view a sample image it from 'http://127.0.0.1:8000/media/imageUpload/example.jpg' and it seems it is working for media.
However, this tutorial involves image upload with #exempt_csrf and #requires_csrf_token and it looks like it is causing csrf issue.
I tried workarounds(ex: https://github.com/editor-js/image/issues/45), adding additionalRequestHeaders with csrf token but it keeps showing the same error.
Here is my code:
#urls.py(app)
from django.urls import path, include
from .views import upload_image_view
from django.views.decorators.csrf import csrf_exempt, csrf_protect
urlpatterns = [
path('imageUpload/', csrf_exempt(upload_image_view)),
]
#urls.py (project)
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
from django.views.generic.base import TemplateView
urlpatterns = [
path('post/', include('post.urls'), name='post'),
path('', TemplateView.as_view(template_name='home.html'), name='home'),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
#views.py (functon part)
from django.shortcuts import render, get_object_or_404, reverse, redirect
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.views.decorators.csrf import ensure_csrf_cookie, requires_csrf_token, csrf_exempt
from django.core.files.storage import FileSystemStorage
#requires_csrf_token
def upload_image_view(request):
f=request.FILES['image']
fs = FileSystemStorage()
filename = str(f).split('.')[0]
file = fs.save(filename, f)
fileurl = fs.url(file)
return JsonResponse({'success' :1, 'file': {'url': fileurl }})
#models.py
class Post(models.Model):
title = models.CharField(max_length=200)
desc = EditorJsField(
editorjs_config={
"tools": {
"Table": {
"disabled": False,
"inlineToolbar": True,
"config": {"rows": 2, "cols": 3,},
},
"Image": {
"config" : {
"endpoints": {
"byFile" : 'http://127.0.0.1:8000/media/imageUpload/',
"byUrl": 'http://localhost:8000/media/imageUpload/',
},
"additionalRequestHeaders":[{"Content-Type":'multipart/form-data', "X-CSRF-TOKEN": "{{csrf_token}}" }] #setting it as token(like example from github) won't work because it shows error that it is not defined. I don't know how to call from models.py any idea?
}
}
}
}
)
I tried other variations on x-csrf-token like call token and use 'const csrftoken = getCookie('csrftoken');' in javascript and etc but I am keep trying to figure out.
Any ideas?
So turns out revising endpoint solved the problem.
Previously I used full url of media folder like 'http://127.0.0.1:8000/media/imageUpload/'. This gave me Forbidden csrf error.
I've also tried using '/imageUpload/' but it gave me 'not found' error.
Because there is a main project and post app is followed, i had to specify the route like this : '/post/imageUpload/'

Django Url NoReverseMatch at issue

I don't know why I am getting this issue with my code. I've tried a bunch of stuff to resolve it but I can't
NoReverseMatch at /property/
Reverse for 'property_detail' not found. 'property_detail' is not a valid view function or pattern name.
Request Method:GETRequest URL:http://127.0.0.1:8000/property/Django Version:3.0.5Exception Type:NoReverseMatchException Value:
Reverse for 'property_detail' not found. 'property_detail' is not a valid view function or pattern name.
Exception Location:E:\django_projects\env\lib\site-packages\django\urls\resolvers.py in _reverse_with_prefix, line 677Python Executable:E:\django_projects\env\Scripts\python.exePython Version:3.7.4Python Path:
['E:\\django_projects\\hotel\\src\\project',
'E:\\django_projects\\env\\Scripts\\python37.zip',
'c:\\users\\user\\appdata\\local\\programs\\python\\python37\\DLLs',
'c:\\users\\user\\appdata\\local\\programs\\python\\python37\\lib',
'c:\\users\\user\\appdata\\local\\programs\\python\\python37',
'E:\\django_projects\\env',
'E:\\django_projects\\env\\lib\\site-packages']
html code
<ul class="probootstrap-main-nav">
<li class="active">Home</li>
<li>Properties</li>
<li>Agents</li>
<li>About</li>
<li>Contact</li>
</ul>
project/urls (project directory)
urlpatterns = [
path('admin/', admin.site.urls),
path('property/', include('property.urls', namespace='property')),
path('agents/', include('agents.urls', namespace='agents')),
path('about/', include('about.urls', namespace='about')),
path('contact/', include('contact.urls', namespace='contact')),
]
propert/urls (app)
from django.urls import path
from . import views
app_name= 'property'
urlpatterns = [
path('', views.property_list, name='property_list'),
path('<int:id>', views.property_detail, name='property_detail'),
]
property/views
from django.shortcuts import render
from .models import (Property, Category)
from .forms import ReserveForm
def property_list(request):
property_list = Property.objects.all()
template = 'list.html'
context = {
'property_list': property_list,
}
return render(request, template, context)
def property_detail(request, id):
property_detail = Property.objects.get(id=id)
if request.method == 'POST':
reserve_form = ReserveForm(request.POST)
if reserve_form.is_valid():
reserve_form.save()
else:
reserve_form = ReserveForm()
return render(request, 'detail.html', {
'property_detail': property_detail,
'reserve_form': reserve_form
})

Django Rest Framework GET request with params

I'm trying to make a get request with params (srcFilename) in Django Rest Framework. I'm pretty confused about where to add the "req.query.srcFilename" (as it would be in javascript) in django. I read I have to add the complete url with the params in "<>" as shown in the code below, but it wont find the url.
views.py:
#api_view(['GET'])
def api_generate_signed_url(request, srcFilename):
print(f'srcFilename: {srcFilename}')
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(srcFilename)
if request.method == 'GET':
url = blob.generate_signed_url(
version="v4",
# This URL is valid for 15 minutes
expiration=datetime.timedelta(minutes=15),
# Allow GET requests using this URL.
method="GET",
)
print(f"Generated GET signed URL: {url}")
return Response(url)
urls.py:
from django.urls import include, path
from rest_framework import routers
from .views import api_generate_signed_url
router = routers.DefaultRouter()
urlpatterns = [
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
path(r'signedurl?srcFilename=<srcFilename>', api_generate_signed_url),
]
When trying this in Postman I get the following error:
The current path, signedurl, didn't match any of these.
Postman screenshot
You have to change your path as below...
path('signedurl', api_generate_signed_url),
No need to write ?srcFilename=<srcFilename>. Just remove it.
Then in your view access your request parameters through the QueryDict request.query_params.get('srcFilename').

NoReverseMatch pattern not found in django2

NoReverseMatch found for a url i have tried and
{% url '/feedback/form/' %}
i am using a feedback app.
#feedback\urls.py
from django.urls import path, include
from .views import request_feedback
urlpatterns = [
path('form/', request_feedback, name = 'get_feedback' ),
]
#feedback\views.py
def request_feedback(request):
if request.method == 'POST':
feedback_form = FeedBackForm(request.POST)
if feedback_form.is_valid():
feedback_form.save()
return redirect('')
else:
feedback_form = FeedBackForm()
return render(request, 'feedback/feedbackform.html', {'feedback_form':feedback_form})
#webapp\urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('feedback/', include("feedback.urls")),
path('user/',include("user.urls")),
]
i am getting this error
NoReverseMatch at /feedback/form/
Reverse for '' not found. '' is not a valid view function or pattern name
i am using python 3.7 and django 2
i do mitigate this problem

django-rest-framework login via Ajax returns HTML

I'm using the django-rest-framework and trying to login using Ajax, but the login API is returning HTML instead of JSON.
My configs:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
)
}
And the Ajax call:
$.ajax({
url: '/api-auth/login/',
method: 'POST',
data: "username=xxxxx&password=123",
headers: {
Accept: 'application/json'
},
success: function(resp) {
console.log(resp);
},
error: function(resp) {
console.error(resp);
}
});
Even if I'm specifying the Accept header, it always returns text/html.
Am I using the wrong endpoint?
I'm using JSONWebToken for external clients (ie, mobile) and the SessionAuthentication for same domain web requests. I expect the SessionAuthentication to set the cookie I can use to make further requests once logged in. If the login fails, I expect the API to return the error in JSON (ie, "Invalid username and password").
urls.py (important parts)
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
...
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^api-token-auth/', obtain_jwt_token),
url(r'^api/', include(router.urls)),
]
Using:
Django==1.11
djangorestframework==3.7.7
djangorestframework-jwt==1.11.0
If you want to set a http only cookie you just have to add the parameter 'JWT_AUTH_COOKIE': 'you_cookie_name', inside the dictionary JWT_AUTH in settings.py also remember use the view that provide django_rest_framework_jwt located in from rest_framework_jwt.views import obtain_jwt_token in your case api-token-auth/'