I followed the turial at django-rest-framework quickstart
I have two URLs namely /users/ and /groups/
The group works perfectly:
but the user url gets a error like this:
server error 500
I set DEBUG to False then add some host to ALLOWED_HOST in settings.py:
DEBUG = False
ALLOWED_HOSTS = [
'127.0.0.1',
'localhost'
]
INSTALLED_APPS = [
'rest_framework',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
my urls.py:
from django.contrib import admin
from django.urls import include, path
from rest_framework import routers
from django_rest.django_rest_app import views
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
this is my serializers.py:
from django.contrib.auth.models import User, Group
from rest_framework import serializers
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['url','username','email','group']
class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
fields = ['url','name']
and this is my views.py:
from django.shortcuts import render
from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from rest_framework import permissions
from django_rest.django_rest_app.serializers import UserSerializer, GroupSerializer
class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
permission_classes = [permissions.IsAuthenticated]
class GroupViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Group.objects.all()
serializer_class = GroupSerializer
permission_classes = [permissions.IsAuthenticated]
UPDATE
when I set DEBUG to True again, I got this:
Field name group is not valid for model User
I'm still a beginner, I hope you can help
Thanks.
You have made mistake in UserSerializer class
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['url','username','email','group']
Please change as follows
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['url','username','email','groups']
there is no field named 'group' in User model. Instead it is 'groups'.
Related
I need to get just one product object in my VeiwSet based on a given slug, I looked into the docs, but I can't find any solution to this problem. I need to get the slug from the url path aswell, but I don't know how to do it too. Obviously the code below doesn't work.
product/serializers.py
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
image = serializers.ImageField(required=True)
class Meta:
model = Product
fields = ("name", "description", "slug", "id", "price", "stock", "image", "category")
product/views.py
from django.http.response import JsonResponse
from rest_framework import serializers, viewsets
from rest_framework.response import Response
from django.http import JsonResponse
from .serializers import ProductSerializer
from .models import Product
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all().order_by('name')
serializer_class = ProductSerializer
class ProductDetailViewSet(viewsets.ViewSet, slug):
queryset = Product.objects.filter(slug=slug)
serializer_class = ProductSerializer
product/urls.py
from rest_framework import routers, urlpatterns
from django.urls import path, include
from .views import ProductViewSet, ProductDetailiewSet
router = routers.DefaultRouter()
router.register(r'', ProductViewSet)
urlpatterns = [
path('<str:slug>/',),
path('', include(router.urls))
]
ViewSets allows you to combine ListView and DetailView into one view.
So you don't need two different views to handle the both actions.
Now if you want to use slug in the url instead of the id by default, you just have to specify lookup_field in the serializer and the view like this :
serializers.py
class ProductSerializer(serializers.ModelSerializer):
image = serializers.ImageField(required=True)
class Meta:
model = Product
fields = ("name", "description", "slug", "id", "price", "stock", "image", "category")
lookup_field = 'slug'
extra_kwargs = {
'url': {'lookup_field': 'slug'}
}
views.py
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all().order_by('name')
serializer_class = ProductSerializer
lookup_field = 'slug'
urls.py
router = routers.DefaultRouter()
router.register(r'', ProductViewSet)
urlpatterns = [
url(r'', include(router.urls)),
]
Now you can query http://localhost:8000/ for products list and http://localhost:8000/product_slug for product detail with product_slug as slug.
More about Django ViewSets and Routers
I have a User table that has some attributes where the Password is being stored as a String. I am trying to store it as an encrypted string using bcrypt, but for some reason it is not changing and the password continues to be the one before encryption.
I have this in my settings.py:
enter image description here
And the method to add my User to the table is in views.py as this:
enter image description here
What am I doing wrong and how can I fix it?
I think you shouldn't do custom encryption. Django already has an encryption system. You can easily integrate bcrpyt as in the documentation. Then all you have to do is;
passwd = user_data['passwd']
user = user_serializer.save()
user.set_password(passwd)
user.save()
EDIT:
Changing password Django doc
Your django configurations are wrong, they should be these:
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.Argon2PasswordHasher',
]
this is not the why you should create users with API
first install django rest framework (DRF)
then do this
serializers.py
from django.conf import settings
from django.contrib.auth.models import User
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
"""Serializes a user object"""
class Meta:
model = User
fields = ('__all__')
extra_kwargs = {
'password': {
'write_only': True,
'style': {'input_type': 'password'}
}
}
def create(self, validated_data):
"""Create and return new user"""
user = User.objects.create_user(**validated_data)
return user
permissions.py
from rest_framework import permissions
class UpdateOwnUser(permissions.BasePermission):
"""Allow user to just change their own profile"""
def has_object_permission(self, request, view, obj):
"""Check if user is trying to change their own profile"""
if request.method in permissions.SAFE_METHODS:
return True
return obj.id == request.user.id
views.py
from rest_framework.authentication import TokenAuthentication
from rest_framework import viewsets
from . import permissions, serializers
class UserViewSet(viewsets.ModelViewSet):
"""Handle creating and updating profiles"""
serializer_class = serializers.UserSerializer
queryset = User.objects.all()
authentication_classes = (TokenAuthentication,)
permission_classes = (permissions.UpdateOwnUser,)
urls.py
from django.urls import include, path
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter()
router.register('profile', views.UserProfileViewSet)
urlpatterns = [
path('', include(router.urls)),
]
in the root url.py:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('profiles_api.urls')),
]
I am trying to use django-autocomplete-light 3.2.1 in my Django (1.10) project with python (3.5) and I found great difficulty in using it. Then I try to follow the live demo shown in the tutorial and pull down all file to my local drive for replication (like the one on http://dal-yourlabs.rhcloud.com/select2_outside_admin/), however in vain. To me, I want to make my local demo work so that I can work my own one based on this.
Specifically, when I follow the following codes and run the site, it shows the errors of NoReverseMatch at /select2_outside_admin/ with description of Reverse for 'linked_data' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: [] I have no idea what is going wrong. I attached my codes as below and please advise what to do if you know the solution. Many thanks:
settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'select2_outside_admin',
# Autocomplete
'dal',
# Enable plugins
'dal_select2',
'dal_queryset_sequence',
]
urls.py:
from django.conf.urls import url, include
from django.contrib import admin
from .views import UpdateView
urlpatterns = [
url(r'^admin/', admin.site.urls),
# url(r'^select2_outside_admin/', include('select2_outside_admin.urls')),
url(
r'^select2_outside_admin/$',
UpdateView.as_view(),
name='select2_outside_admin',
),
]
models.py:
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
#python_2_unicode_compatible
class TModel(models.Model):
name = models.CharField(max_length=200)
test = models.ForeignKey(
'self',
null=True,
blank=True,
related_name='related_test_models'
)
owner = models.ForeignKey(
'auth.user',
null=True,
blank=True,
related_name='owned_linked_models',
)
for_inline = models.ForeignKey(
'self',
null=True,
blank=True,
related_name='inline_test_models'
)
def __str__(self):
return self.name
forms.py:
from dal import autocomplete
from django import forms
from .models import TModel
class TForm(forms.ModelForm):
def clean_test(self):
owner = self.cleaned_data.get('owner', None)
value = self.cleaned_data.get('test', None)
if value and owner and value.owner != owner:
raise forms.ValidationError('Wrong owner for test')
return value
class Meta:
model = TModel
fields = ('name', 'owner', 'test')
widgets = {
'test': autocomplete.ModelSelect2(url='linked_data',
forward=('owner',))
}
class Media:
js = (
'linked_data.js',
)
views.py:
from django.shortcuts import render
from django.core.urlresolvers import reverse_lazy
from django.views import generic
from select2_outside_admin.forms import TForm
from select2_outside_admin.models import TModel
# Create your views here.
class UpdateView(generic.UpdateView):
model = TModel
form_class = TForm
template_name = 'select2_outside_admin.html'
success_url = reverse_lazy('select2_outside_admin')
def get_object(self):
return TModel.objects.first()
I am unable to do PUT operation in Django rest framework, I am able to GET, POST, DELETE operation.
This is the error
I have tried using #api_view but there also its not,
I mostly refer the djangorestframework website
Below is my code:
serializers.py
from rest_framework import serializers
from snippets.models import Snippet
#from django.contrib.auth.models import *
class SnippetSerializer(serializers.ModelSerializer):
class Meta:
model = Snippet
fields = ('id','title','code')
Models.py
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Snippet(models.Model):
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default='')
code = models.CharField(max_length=100, blank=True, default='')
class Meta:
ordering = ('created',)
Views.py
from rest_framework import viewsets
from rest_framework.decorators import api_view
from snippets.serializers import SnippetSerializer
class SnippetViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = Snippet.objects.all().order_by('id')
serializer_class = SnippetSerializer
urls.py
rom django.conf.urls import url, include
from rest_framework import routers
from django.contrib import admin
from snippets import views
router = routers.DefaultRouter()
router.register(r'snippet', views.SnippetViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
Looking at the documentation of DefaultRouter, it looks like that PUT method can only be used with {basename}-detail type of URLs.
While you are using it directly on /snippet url where it is not allowed.
Im trying to create a basic view using the Django REST framework without requiring authentication.
Settings.py
THIRD_PARTY_APPS = (
'south', # Database migration helpers:
'crispy_forms', # Form layouts
'rest_framework',
)
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
)
}
urls.py
router = routers.DefaultRouter()
router.register(r'ticket', views.TicketViewSet)
urlpatterns = patterns('',
url(r'^', include(router.urls)),
url(r'^test', include('rest_framework.urls', namespace='rest_framework')),
)
Serializers
from django.contrib.auth.models import User, Group
from rest_framework import serializers
class TicketInputSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Abc
fields = ('test')
Models
from django.db import models
class Abc(models.Model):
test = models.CharField(max_length=12)
Error
When trying to get to the URI i get the following,
Page Not Found 404
Using the URLconf defined in config.urls, Django tried these URL patterns, in this order:
^test ^login/$ [name='login']
^test ^logout/$ [name='logout']
Any ideas ?