django rest_framework viewset has no route - django

I started a new django application with django rest_framework. One thing is odd though - when I try the example from the quickstart it works fine: I get a route at http://localhost:8000/users/ that I can query. But it doesn't work with my own app which is as minimal as it could be. My route http://localhost:8000/listings/ is not available and I get no error. I'm using django 1.8.2 and djangorestframework 3.1.3.
settings.py:
#...
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework_swagger',
'debug_toolbar',
'listing',
)
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
]
}
#...
urls.py:
from rest_framework import routers, serializers, viewsets
from listing.models import Listing
class ListingSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Listing
fields = ('description',)
class ListingViewSet(viewsets.ViewSet):
queryset = Listing.objects.all()
serializer_class = ListingSerializer
router = routers.DefaultRouter()
router.register(r'listings', ListingViewSet)
urlpatterns = router.urls
models.py:
from django.db import models
class Listing(models.Model):
description = models.TextField()
Edit:
The error:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/listings/
Using the URLconf defined in djangoway.urls, Django tried these URL patterns, in this order:
^__debug__/
^$ [name='api-root']
^\.(?P<format>[a-z0-9]+)$ [name='api-root']
The current URL, listings/, didn't match any of these.
Edit:
Answered my question and took the code down, because there was nothing odd with it.

I should have used the ModelViewSet:
class ListingViewSet(viewsets.ModelViewSet):
^^^^^
Thanks to xordoquy for pointing it out in the issue I opened.

Related

How can i fix Page not found 404 in django?

Hi ive been coding my first website and then try running the product page I get this error
*Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/products
Using the URLconf defined in myshop.urls, Django tried these URL patterns, in this order:
admin/
The current path, products, didn't match any of these.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.*
how can I solve this? Here is my code...
my views page code
from django.http import HttpResponse
from django.shortcuts import render
def index(request):
return HttpResponse('Hello world')
def new(request):
return HttpResponse('New Products')
productsurls code
from django.urls import path
from . import views
urlpatterns = [
path('', views.index),
path('new', views.new)
]
myshopurls
from django.contrib import admin
from django.urls import path, include
urlpatterns = {
path('admin/', admin.site.urls),
path('products/', include('products.urls'))
}
Most probably, you are facing this problem because you have not include your app "products" in the "settings.py" file.
-> After checking your code I can conclude that"myshop" is your project and "products" is your app.
So, you will have to go in settings.py file under which you will find a list "INSTALLED_APPS".
Inside INSTALLED_APPS -> You will have to include your app.
Go to "apps.py" file of the "products" app and copy the name of the "config" class.
After that in your settings.py file, you will have to write 'products.apps.(paste the name of config class)'.
Most probably name of your config class will be "ProductsConfig" -> So, you will have to write 'products.apps.ProductsConfig',
Hope it will work !
You have to include the app under INSTALLED_APPS in settings.py file.
So your settings.py file should read like so
INSTALLED_APPS = [
# Built In Apps
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# User Defined Apps
'product.apps.ProductConfig',
]
Tip - If you are confused as to how to include the name under installed Apps. It should be like so
<myapp>.apps.<name_of_class_in_myapp/apps.py_file>
Basically navigate to your app folder -> apps.py file and check the name of the class. It will be like so
from django.apps import AppConfig
class ProductConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'product'
You want the name of this class. ProductConfig.
Note - Local apps should always be added at the bottom because Django executes the
INSTALLED_APPS setting from top to bottom. We want the core Django apps to be available before our app.
The reason for listing the app like
'product.apps.ProductConfig',
is because it is best practice and helps if in future if you decide to use Django Signals.

How to replicate django authentication in several services

We have a web app using Django. We have the authentication system setup as described below. Now, we would like to take some part of the application to an independent service, but we would like to have the same valid token/authentication system. The new service will be using Django too, probably, so I would like to know if this is even possible or what options do I have to implement this behavior.
In the case that we do not use Django in the new service, there would be a way to still use the same logic to authenticate requests on the two services?
Authentication system
Right now, we are authenticating the requests using the rest_framework module, more precisely, the TokenAuthentication class.
This is the configuration:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
...
'rest_framework',
'rest_framework.authtoken',
...
}
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated'
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'module.authentications.AuthorizedAuthentication',
)
}
And the code we use to authorize the requests:
import logging
from rest_framework.authentication import TokenAuthentication
from rest_framework.exceptions import AuthenticationFailed
class AuthorizedAuthentication(TokenAuthentication):
def authenticate(self, request):
response = TokenAuthentication.authenticate(self, request)
if response is None:
return None
return response
To authenticate in the views, we do something like this:
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
class SomeView(APIView):
permission_classes = (IsAuthenticated,)
EDIT
The code is not complete so please do not comment about it, I have just copied to show you a simplified example about our configuration.

from .models import profile ImportError: cannot import name 'profile'

I used following code but got an error:
admin.py
from django.contrib import admin
from .models import profile
class profileAdmin(admin.ModelAdmin):
class Meta:
model = profile
admin.site.register(profile,profileAdmin)
__________________model.py__________________________
from django.db import models
class profiles(models.Model):
name=models.CharField(max_length=120)
#description=models.TextField(null=True)#null value updated in data base
description=models.TextField(default='description default text')
def _unicode_(self):
#def _str_(self):
return self.name
____________________________settings.py_____
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'profiles',
]
Error traceback:
from .models import profile
ImportError: cannot import name 'profile'
Can anyone suggest how to fix this? I'm using python3.4
if in your case profile means Profile class in models.py, then it should be:
from .models import Profile
Notice the capital 'P'. You can also share your models.py so we could see what is probably not right.
now after some research work i have the solution of the problem that why someone is not able to import "profile" into admin.py.
____________admin.py (corrected and working for above models.py and settings.py)_____)
from django.contrib import admin
from .models import profiles #
class profileAdmin(admin.ModelAdmin):
class Meta:
model = profiles
admin.site.register(profiles,profileAdmin)
People have misconception that one should use from .models import Profile instead of from .models import profile in models.py but it's not like that.
we can use any one of them depends upon what is in settings.py and models.py (in INSTALLED_APPS )
(_____________ in settings.py_________)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'profiles',
]
i had used profiles so in my case
from .models import profiles
worked well.
and 2nd thing is class name is profiles in models.py class profiles(models.Model):
________models.py_______
from django.db import models
class profiles(models.Model):
name=models.CharField(max_length=120)
#description=models.TextField(null=True) null value updated in data base
description=models.TextField(default='description default text')
def _unicode_(self):
#def _str_(self):
return self.name
so class Meta:
model = profiles
so, in _______________admin.py_____________ model=profiles has used which is same as class name in ______________models.py_________
class Meta:
model = profiles
admin.site.register(profiles,profileAdmin)
thanks... to all
regards,
Shubham Kumar(UIETH,Panjab University)
shubh2ai#gmail.com

django-axes lockout not working

Has anyone here successfully configured django-axes? Axes is a module which provides you with the ability to lock out a user after a specified number of unsuccessful login attempts. I'm having three problems which I haven't been able to solve. First, my application continues to allow me to try to login even if I've exceeded the failure limit, second my site isn't displaying the lockout template if I exceed the failure limit, and third my administrative site isn't showing any login failures. I've read the docs on Github but I still don't see what I'm doing wrong. My files are shown below. Thanks for your help.
# Relevant settings in settings.py
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'login',
'axes',
)
# MIDDLEWARE_CLASSES contains usual classes
MIDDLEWARE_CLASSES += (
'axes.middleware.FailedLoginMiddleware',
)
AXES_LOGIN_FAILURE_LIMIT = 1
import datetime as dt
delta = dt.timedelta(minutes=1)
AXES_COOLOFF_TIME = delta
AXES_LOCKOUT_URL = '/accounts/locked_out/'
AXES_LOCKOUT_TEMPLATE = 'registration/locked_out.html'
# Relevant routes in urls.py
urlpatterns = patterns('',
# This is my login view, nothing special there
url(r'^$', 'login.views.firewall_login'),
# The view for Axes lockout
url(r'^accounts/locked_out/$',
'login.views.locked_out',
{'template': 'registration/locked_out.html'}),
url(r'^admin/', include(admin.site.urls)),
)
# views.py
def locked_out(request, template):
"""User is redirected here after they're locked out."""
return render(request, template)
Add this to your setting.py:
AUTHENTICATION_BACKENDS = [
# AxesBackend should be the first backend in the AUTHENTICATION_BACKENDS list.
'axes.backends.AxesBackend',
# Django ModelBackend is the default authentication backend.
'django.contrib.auth.backends.ModelBackend',
]
All I can help with is that you need to add
AXES_ENABLE_ACCESS_FAILURE_LOG = True # log access failures to the database.
Not sure about the other questions myself, unfortunately

Why do I get "CSRF cookie not set" when POST to Django REST framework?

I am getting the error "CSRF cookie not set" returned when trying to POST to a simple test app using the Django REST framework. I've tried it with Django 1.4 and the Django 1.6.2. I am using the Django REST framework v 2.3.13.
I have tried using the #csrf_exempt decorator, but it doesn't help.
This is a very simple app, with no user registration / login etc.
Any ideas why I'm getting this error?
Update: I have updated my urls.py as shown below and it is now working!!
Here's my code:
urls.py
from django.conf.urls import patterns, url
from quickstart import views
urlpatterns = patterns('',
url(r'^api_add/$', views.api_add, name='api_add'),
)
views.py
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
#api_view(['POST'])
def api_add(request):
return Response({"test": 'abc'})
settings.py
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
)
post.sh
curl -X POST -H "Content-Type: application/json" -d '
{
"name": "Manager",
"description": "someone who manages"
}' http://127.0.0.1:8000/api_add/
Use the #csrf_exempt-decorator:
from django.views.decorators.csrf import csrf_exempt
#api_view(['POST'])
#csrf_exempt
def api_add(request):
return Response({"test": 'abc'})
Update:
If you never need csrf-checks, remove the middleware. Seach for MIDDLEWARE_CLASSES in settings.py and remove 'django.middleware.csrf.CsrfViewMiddleware',.
Django-Rest-Framework automatically adds #csrf_exempt to all APIView (or #api_view).
Only exception is the SesssionAuthentication which forces you (correctly) to use CSRF, see the docs on CSRF or the DRF source
I solved this like this:
#api_view(['POST'])
#csrf_exempt
def add(request):
....
to:
#csrf_exempt
#api_view(['POST'])
def add(request):
.....
I had the similar issue. I tried using #csrf_exempt but it did not work.
I changed ALLOWED_HOSTS = '*' to ALLOWED_HOSTS = [] and it worked for me on local.