I'm new to django rest_framework and have and issue, i've extended the auth_user as per the django docs, but is giving me a hard time...
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)
national_id = models.CharField(max_length=10, blank=True, null=True)
mobile = models.CharField(max_length=10)
pin = models.IntegerField()
pattern = models.IntegerField(blank=True, null=True)
fingerprint = models.CharField(max_length=45, blank=True, null=True)
class Meta:
managed = False
db_table = 'user_profile'
serializers.py
class UserSerializer(serializers.ModelSerializer):
national_id = serializers.CharField(source='userprofile.national_id', allow_null=True, required=False)
mobile = serializers.CharField(source='userprofile.mobile')
pin = serializers.IntegerField(source='userprofile.pin', write_only=True)
pattern = serializers.IntegerField(source='userprofile.pattern', write_only=True)
fingerprint = serializers.CharField(source='userprofile.fingerprint', write_only=True, allow_null=True, required=False)
class Meta:
model = User
fields = ('id', 'username', 'password', 'first_name', 'last_name', 'email', 'national_id', 'mobile', 'pin', 'pattern', 'fingerprint')
write_only_fields = ('password',)
read_only_fields = ('last_login', 'is_superuser', 'is_staff', 'is_active', 'date_joined')
def create(self, validated_data):
user = User(
username=validated_data['username'],
first_name=validated_data['first_name'],
last_name=validated_data['last_name'],
email=validated_data['email'],
)
user.set_password(validated_data['password'])
user.save()
userprofile = UserProfile(
user=user,
national_id=validated_data['national_id'],
mobile=validated_data['mobile'],
pin=validated_data['pin'],
pattern=validated_data['pattern'],
fingerprint=validated_data['fingerprint'],
)
userprofile.save()
return user
views.py
class UserView(viewsets.ModelViewSet):
serializer_class = UserSerializer
queryset = get_user_model().objects
urls.py
from django.conf.urls import include, url
from django.contrib import admin
from rest_framework.routers import DefaultRouter
from restful.views import *
router = DefaultRouter()
router.register(r'availability-notification', AvailabiltyNotificationView)
router.register(r'bank', BankView)
router.register(r'recipient', RecipientView)
router.register(r'user', UserView)
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^admin/', admin.site.urls),
but keeps giving me:
Environment:
Request Method: POST Request URL: http://localhost:8000/user/
Django Version: 1.10.2 Python Version: 3.5.2 Installed Applications:
['django.contrib.admin', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.staticfiles',
'rest_framework', 'restful'] Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\core\handlers\exception.py"
in inner
39. response = get_response(request)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\core\handlers\base.py"
in _get_response
187. response = self.process_exception_by_middleware(e, request)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\core\handlers\base.py"
in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\views\decorators\csrf.py"
in wrapped_view
58. return view_func(*args, **kwargs)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\viewsets.py"
in view
87. return self.dispatch(request, *args, **kwargs)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\views.py"
in dispatch
474. response = self.handle_exception(exc)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\views.py"
in handle_exception
434. self.raise_uncaught_exception(exc)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\views.py"
in dispatch
471. response = handler(request, *args, **kwargs)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\mixins.py"
in create
21. self.perform_create(serializer)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\mixins.py"
in perform_create
26. serializer.save()
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\serializers.py"
in save
192. self.instance = self.create(validated_data)
File "C:\Users\echavez\Source\ws\restful\serializers.py" in create
45. national_id=validated_data['national_id'],
Exception Type: KeyError at /user/ Exception Value: 'national_id'
I know this is a newbie question, but, i really need help!
Thanks in advance.
You are getting profile data in wrong way.
validated_data is a dictionary of user and profile data which you are going to save separately.
Get it like this.
profile_data = validated_data.pop('userprofile')
Note that we poped userprofile data so now you have left only user data in validated_data. So a complete flow will look like below
profile_data = validated_data.pop('userprofile')
user = User.objects.create(**validated_data)
UserProfile.objects.create(user=user, **profile_data)
return user
Take a look here
http://www.django-rest-framework.org/api-guide/serializers/#writable-nested-representations
Thanks to LaL ZaDa who pointed me in the right direction, my code finally looks like this and works:
serializers.py
class UserSerializer(serializers.ModelSerializer):
national_id = serializers.CharField(source='userprofile.national_id', allow_null=True, required=False)
mobile = serializers.CharField(source='userprofile.mobile')
pin = serializers.IntegerField(source='userprofile.pin', write_only=True)
pattern = serializers.IntegerField(source='userprofile.pattern', write_only=True)
fingerprint = serializers.CharField(source='userprofile.fingerprint', write_only=True, allow_null=True, required=False)
bank_accounts = UserBankAccountSerializer(many=True)
class Meta:
model = User
fields = ('id', 'username', 'password', 'first_name', 'last_name', 'email', 'national_id', 'mobile', 'pin', 'pattern', 'fingerprint', 'bank_accounts')
write_only_fields = ('password',)
read_only_fields = ('last_login', 'is_superuser', 'is_staff', 'is_active', 'date_joined')
def create(self, validated_data):
user = User(
username=validated_data['username'],
first_name=validated_data['first_name'],
last_name=validated_data['last_name'],
email=validated_data['email'],
)
user.set_password(validated_data['password'])
user.save()
profile_data = validated_data.pop('userprofile')
userprofile = UserProfile(
user=user,
national_id=profile_data['national_id'],
mobile=profile_data['mobile'],
pin=profile_data['pin'],
pattern=profile_data['pattern'],
fingerprint=profile_data['fingerprint'],
)
userprofile.save()
return user
Cause, this is not exactly a nested model (the bank_accounts, are nested), so when i do like this:
profile_data = validated_data.pop('userprofile')
user = User.objects.create(**validated_data)
UserProfile.objects.create(user=user, **userprofile)
return user
was throwing me...
Environment:
Request Method: POST Request URL: http://localhost:8000/user/
Django Version: 1.10.2 Python Version: 3.5.2 Installed Applications:
['django.contrib.admin', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.staticfiles',
'rest_framework', 'restful'] Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\core\handlers\exception.py"
in inner
39. response = get_response(request)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\core\handlers\base.py"
in _get_response
187. response = self.process_exception_by_middleware(e, request)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\core\handlers\base.py"
in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\views\decorators\csrf.py"
in wrapped_view
58. return view_func(*args, **kwargs)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\viewsets.py"
in view
87. return self.dispatch(request, *args, **kwargs)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\views.py"
in dispatch
474. response = self.handle_exception(exc)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\views.py"
in handle_exception
434. self.raise_uncaught_exception(exc)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\views.py"
in dispatch
471. response = handler(request, *args, **kwargs)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\mixins.py"
in create
21. self.perform_create(serializer)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\mixins.py"
in perform_create
26. serializer.save()
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\rest_framework\serializers.py"
in save
192. self.instance = self.create(validated_data)
File "C:\Users\echavez\Source\ws\restful\serializers.py" in create
49. user = User.objects.create(**validated_data)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\db\models\manager.py"
in manager_method
85. return getattr(self.get_queryset(), name)(*args, **kwargs)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\db\models\query.py"
in create
397. obj = self.model(**kwargs)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\contrib\auth\base_user.py"
in init
68. super(AbstractBaseUser, self).init(*args, **kwargs)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\db\models\base.py"
in init
550. setattr(self, prop, kwargs[prop])
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\db\models\fields\related_descriptors.py"
in set
500. manager.set(value)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\db\models\fields\related_descriptors.py"
in set
687. self.add(*objs, bulk=bulk)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\db\models\fields\related_descriptors.py"
in add
597. self.field.name: self.instance,
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\db\models\query.py"
in update
637. rows = query.get_compiler(self.db).execute_sql(CURSOR)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\db\models\sql\compiler.py"
in execute_sql
1148. cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\db\models\sql\compiler.py"
in execute_sql
824. sql, params = self.as_sql()
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\db\models\sql\compiler.py"
in as_sql
1102. val.prepare_database_save(field),
File
"C:\Users\echavez\Envs\YEiPii\lib\site-packages\django\db\models\base.py"
in prepare_database_save
999. raise ValueError("Unsaved model instance %r cannot be used in an ORM query." % self)
Exception Type: ValueError at /user/ Exception Value: Unsaved model
instance cannot be used in an ORM query.
Now i'll finish the create to include the nested one and the update and delete...
Thanks LaL
Related
I have this Serializer class for my User model:
serializers.py
class UserCreateSerializer(serializers.ModelSerializer):
"""User django serilization"""
key = serializers.StringRelatedField(source='key.token', read_only=True)
class Meta:
model = User
fields = ['phonenumber','id','email', 'username', 'key' ]
def create(self, validate_data):
user = User(**validate_data)
user.save()
return user
and this views.py
class UserListView(ListAPIView):
'''listing all users'''
permission_classes = (AllowAny,)
pagination_class = SmallPagination
throttle_classes = (UserRateThrottle, AnonRateThrottle,)
serializer_class = UserCreateSerializer
queryset = User.objects.all()
filter_backends = (filters.SearchFilter,)
search_fields = ('username', 'phonenumber', 'email')
I include 'rest_framework.authtoken', in my settings.py
and made a signal for Tokens from django Restframe work documentation.
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
urls.py
urlpatterns = [
re_path(r'^users/$', views.UserListView.as_view(), name='user-list'),]
so when I try to load my users List this error occurs :
'NoneType' object has no attribute 'token'
for attr in attrs:
try:
if isinstance(instance, collections.Mapping):
instance = instance[attr]
else:
instance = getattr(instance, attr) ...
except ObjectDoesNotExist:
return None
if is_simple_callable(instance):
try:
instance = instance()
except (AttributeError, KeyError) as exc:
....
the error location is from :
/backend/env/lib/python3.6/site-packages/rest_framework/fields.py in
get_attribute
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/api/users/create/
Django Version: 2.0
Python Version: 3.6.3
Installed Applications:
['django.contrib.admin',
'main.apps.MainConfig',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'stdimage',
'rest_framework.authtoken',
'blog',
'taggit',
'taggit_serializer',
'django.contrib.sites',
'corsheaders',
'webpack_loader']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/django/views/generic/base.py" in view
69. return self.dispatch(request, *args, **kwargs)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
494. response = self.handle_exception(exc)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception
454. self.raise_uncaught_exception(exc)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
491. response = handler(request, *args, **kwargs)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/rest_framework/generics.py" in post
192. return self.create(request, *args, **kwargs)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/rest_framework/mixins.py" in create
22. headers = self.get_success_headers(serializer.data)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/rest_framework/serializers.py" in data
537. ret = super(Serializer, self).data
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/rest_framework/serializers.py" in data
262. self._data = self.to_representation(self.instance)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/rest_framework/serializers.py" in to_representation
491. attribute = field.get_attribute(instance)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/rest_framework/relations.py" in get_attribute
177. return get_attribute(instance, self.source_attrs)
File "/home/babyjesus/workspace/gamespawn/backend/env/lib/python3.6/site-packages/rest_framework/fields.py" in get_attribute
100. instance = getattr(instance, attr)
Exception Type: AttributeError at /api/users/create/
Exception Value: 'NoneType' object has no attribute 'token'
authtoken model has related_name=auth_token to user models. So if you need to get token from user you should use auth_token.key:
key = serializers.StringRelatedField(source='auth_token.token', read_only=True)
I also got stuck in this error. But luckily i found the mistake i was doing.
I know its already been some time now. Still answering this question for newbies stuck in such silly error.
If we have to use Token model we have to mention the same in Installed Apps in settings.py file
'rest_framework.authtoken'
After that do migrate and you will see creation of new tables in the db.
Afterwards you can query the database like this...
Token.objects.all()
and you are good to go now.
Happy coding.
Please help me make REST social connect for provider Vkontakte.
I'm using django-allauth library (https://github.com/pennersr/django-allauth).
And django-rest-auth for REST auth (https://github.com/Tivix/django-rest-auth).
I've already have VKOAuth2Serializer that works fine for login and register.
But connect doesnt' work.
Here is urls:
url(r'^rest-auth/vk/connect/$', views.VkConnect.as_view(), name='vk_connect'),
url(r'^rest-auth/vk/', views.VkLogin.as_view()),
Views:
from allauth.socialaccount.providers.oauth2.client import OAuth2Client
from allauth.socialaccount.providers.vk.views import VKOAuth2Adapter
class VkLogin(CustomSocialLoginView):
adapter_class = VKOAuth2Adapter
serializer_class = VKOAuth2Serializer
client_class = OAuth2Client
callback_url = 'http://localhost:3000'
class VkConnect(SocialConnectView):
adapter_class = VKOAuth2Adapter
#May be here should be something else?
Serializer:
from allauth.socialaccount.helpers import complete_social_login
from rest_auth.registration.serializers import SocialLoginSerializer
from django.utils.translation import ugettext_lazy as _
from requests.exceptions import HTTPError
from rest_framework import serializers
class VKOAuth2Serializer(SocialLoginSerializer):
email = serializers.CharField(required=False, allow_blank=True)
user_id = serializers.CharField(required=False, allow_blank=True)
def validate(self, attrs):
view = self.context.get('view')
request = self._get_request()
if not view:
raise serializers.ValidationError(_("View is not defined, pass it as a context variable"))
adapter_class = getattr(view, 'adapter_class', None)
if not adapter_class:
raise serializers.ValidationError(_("Define adapter_class in view"))
adapter = adapter_class(request)
app = adapter.get_provider().get_app(request)
# Case 1: We received the access_token
if attrs.get('access_token'):
if not attrs.get('user_id') or not attrs.get('email'):
raise serializers.ValidationError(_("Incorrect input. email and user_id is required with access_token."))
access_data = {
'access_token': attrs.get('access_token'),
'user_id': attrs.get('user_id'),
'email': attrs.get('email'),
}
# Case 2: We received the authorization code
elif attrs.get('code'):
self.callback_url = getattr(view, 'callback_url', None)
self.client_class = getattr(view, 'client_class', None)
if not self.callback_url:
raise serializers.ValidationError(_("Define callback_url in view"))
if not self.client_class:
raise serializers.ValidationError(_("Define client_class in view"))
code = attrs.get('code')
provider = adapter.get_provider()
scope = provider.get_scope(request)
client = self.client_class(
request,
app.client_id,
app.secret,
adapter.access_token_method,
adapter.access_token_url,
self.callback_url,
scope
)
access_data = client.get_access_token(code)
if attrs.get('email'):
access_data['email'] = attrs.get('email')
if not access_data.get('email'):
raise serializers.ValidationError(_("Incorrect input. Social account must have email, otherwise send it in email field."))
else:
raise serializers.ValidationError(_("Incorrect input. access_token or code is required."))
social_token = adapter.parse_token({'access_token': access_data['access_token']})
social_token.app = app
try:
login = self.get_social_login(adapter, app, social_token, access_data)
complete_social_login(request, login)
except HTTPError:
raise serializers.ValidationError(_('Incorrect value'))
if not login.is_existing:
login.lookup()
login.save(request, connect=True)
attrs['user'] = login.account.user
return attrs
And here is view for registration/login and urls that works fine:
Please help me make REST connect for Vkontakte.
the project is here:
https://github.com/taime/imetrics
When trying to connect VK - I get error:
Environment:
Request Method: POST
Request URL: http://localhost:8000/rest-auth/vk/connect/
Django Version: 2.0.3
Python Version: 3.5.2
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_filters',
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'django.contrib.sites',
'allauth',
'allauth.account',
'rest_auth.registration',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook',
'allauth.socialaccount.providers.vk',
'allauth.socialaccount.providers.twitter',
'storages',
'core',
'api']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/django/views/decorators/csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/django/views/generic/base.py" in view
69. return self.dispatch(request, *args, **kwargs)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapper
62. return bound_func(*args, **kwargs)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/django/views/decorators/debug.py" in sensitive_post_parameters_wrapper
76. return view(request, *args, **kwargs)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/django/utils/decorators.py" in bound_func
58. return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/rest_auth/views.py" in dispatch
49. return super(LoginView, self).dispatch(*args, **kwargs)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/rest_framework/views.py" in dispatch
494. response = self.handle_exception(exc)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/rest_framework/views.py" in handle_exception
454. self.raise_uncaught_exception(exc)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/rest_framework/views.py" in dispatch
491. response = handler(request, *args, **kwargs)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/rest_auth/views.py" in post
93. self.serializer.is_valid(raise_exception=True)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/rest_framework/serializers.py" in is_valid
236. self._validated_data = self.run_validation(self.initial_data)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/rest_framework/serializers.py" in run_validation
438. value = self.validate(value)
File "/Users/tema/Sites/instametrics/code/core/serializers.py" in validate
73. login = self.get_social_login(adapter, app, social_token, access_data)
File "/Users/tema/Sites/instametrics/.venv/lib/python3.5/site-packages/rest_auth/registration/serializers.py" in get_social_login
58. social_login = adapter.complete_login(request, app, token, response=response)
File "/Users/tema/Sites/instametrics/code/allauth/socialaccount/providers/vk/views.py" in complete_login
54. extra_data = resp.json()['response'][0]
Exception Type: KeyError at /rest-auth/vk/connect/
Exception Value: 'response'
Since VK requires custom provider logic, you need to use serializer with logic defined in VKOAuth2Serializer but with social login state process being set to connect. You can achieve it by creating a subclass of VKOAuth2Serializer with SocialConnectMixin.
So your new serializer and connect view would look the following way:
Serializer:
from rest_auth.registration.serializers import SocialConnectMixin
class VKOAuth2ConnectSerializer(SocialConnectMixin, VKOAuth2Serializer):
pass
View:
class VkConnect(SocialConnectView):
adapter_class = VKOAuth2Adapter
serializer_class = VKOAuth2ConnectSerializer
VK API version field is required now. You can rewrite VKOAuth2Adapter class from github repo
https://github.com/pennersr/django-allauth/blob/master/allauth/socialaccount/providers/vk/views.py
I recently upgraded from drf 2.4 to v3 and have been trying to override the def Create in one of my ViewSets. However when trying to access the request.data that i've saved to a serializer variable i'll receive an error: KeyError at /api/appointments/
'id'
I'm including my ViewSet code, serializer, and the traceback from the error below:
class AppointmentViewSet(viewsets.ModelViewSet):
queryset = Appointment.objects.all()
serializer_class = AppointmentSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,)
def create(self, request):
serializer = AppointmentSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
#get the datetime object from the request data and filter availability objects, datetime stored in attribute .when
avQueryset = Availability.objects.filter(date__range=(serializer.data.when, serializer.data.when))
def pre_save(self, obj):
obj.service_recipient = self.request.user
Serializer
class AppointmentSerializer(serializers.ModelSerializer):
class Meta:
model = Appointment
fields = ('id','availability' , 'business_location', 'services', 'when', 'service_recipient', 'completed')
repr(serializer)
AppointmentSerializer():
id = IntegerField(label='ID', read_only=True)
availability = PrimaryKeyRelatedField(queryset=Availability.objects.all())
business_location = PrimaryKeyRelatedField(queryset=BusinessLocation.objects.all())
services = PrimaryKeyRelatedField(many=True, queryset=Service.objects.all())
when = DateTimeField(allow_null=True, required=False)
service_recipient = PrimaryKeyRelatedField(queryset=User.objects.all())
completed = BooleanField(help_text='Set to true when appointment has been completed.', required=False)
Traceback
Environment:
Request Method: POST
Request URL: http://104.131.110.138/api/appointments/
Django Version: 1.7.1
Python Version: 2.7.6
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'webapp',
'rest_framework')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
111. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/csrf.py" in wrapped_view
57. return view_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/viewsets.py" in view
85. return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/views.py" in dispatch
407. response = self.handle_exception(exc)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/views.py" in dispatch
404. response = handler(request, *args, **kwargs)
File "/home/appointments/appointments/webapp/views.py" in create
57. avQueryset = Availability.objects.filter(date__range=(serializer.data.when, serializer.data.when))
File "/usr/local/lib/python2.7/dist-packages/rest_framework/serializers.py" in data
422. ret = super(Serializer, self).data
File "/usr/local/lib/python2.7/dist-packages/rest_framework/serializers.py" in data
179. self._data = self.to_representation(self.validated_data)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/serializers.py" in to_representation
387. attribute = field.get_attribute(instance)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/fields.py" in get_attribute
277. return get_attribute(instance, self.source_attrs)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/fields.py" in get_attribute
65. instance = instance[attr]
Exception Type: KeyError at /api/appointments/
Exception Value: 'id'
You are using serializer.data when you appear to mean to be using serializer.validated_data. You should really only use serializer.data when you are looking to serialize an existing object, which would require passing an instance into the serialier when you are initializing it.
The issue is that you are not passing an instance into the serializer, so it is expecting that the initial data passed into it can be serialized. This would require the data to have all of the fields on the serializer, including id which doesn't appear to exist.
You can get the validated data, not the serialized data, using serializer.validated_data["when"]. This is specifically mentioned in the documentation for Django REST Framework under deserializing objects.
I have a serializer that verify if some fields are empty or not. If a field is empty all works perfectly, but if all the fields are correct I obtain and AttributeError: 'Fichas' object has no attribute 'update'.
This is the view and the serializer:
views.py
class PublicarFichaViewSet(APIView):
permission_classes = (IsAuthenticated, GroupPermission)
def get_object(self, pk):
try:
return Fichas.objects.get(pk=pk)
except:
raise Http404
def get(self, request, pk, format=None):
ficha = self.get_object(pk)
serializer = PublicarFichaSerializer(ficha)
return Response(serializer.data)
def put(self, request, pk, format=None):
ficha = self.get_object(pk)
serializer = PublicarFichaSerializer(ficha, data=request.DATA)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
serializer.py
class PublicarFichaSerializer(serializers.Serializer):
Centro_responsable = serializers.CharField(required=True, max_length=64)
Autor_de_la_ficha = serializers.CharField(required=True, max_length=64)
Correo_electronico_del_autor_de_la_ficha = serializers.EmailField(required=True)
Autor_del_caso_de_estudio = serializers.CharField(required=True, max_length=64)
Correo_electronico_del_autor_del_caso_de_estudio = serializers.EmailField(required=True)
Tutor = serializers.CharField(required=True, max_length=64)
Correo_electronico_del_tutor = serializers.EmailField(required=True)
Fecha_de_tutela = serializers.DateField(required=True)
Titulo = serializers.CharField(required=True, max_length=64)
Tipo_de_objeto_u_obra_por_su_funcion = serializers.CharField(required=True, max_length=64)
Plano_de_situacion = serializers.CharField(required=True, max_length=64)
Fecha_de_validez_legal = serializers.DateField(required=True)
Ficha_publicada = serializers.BooleanField()
def validate_Ficha_publicada(self, attrs, source):
if not attrs['Ficha_publicada']:
raise serializers.ValidationError("Ficha no publicada")
return attrs
EDIT: The traceback
Environment:
Request Method: POST
Request URL: http://localhost:8000/publicarficha/1/
Django Version: 1.6.5
Python Version: 2.7.6
Installed Applications:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'rest_framework',
'phi_catalogo',
'rest_framework.authtoken',
'django_evolution',
'django.contrib.admin',
'multiselectfield',
'django_extensions',
'pytz')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware')
Traceback:
File "/Users/jian/phi/env/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
112. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/jian/phi/env/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
57. return view_func(*args, **kwargs)
File "/Users/jian/phi/env/lib/python2.7/site-packages/django/views/generic/base.py" in view
69. return self.dispatch(request, *args, **kwargs)
File "/Users/jian/phi/env/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
403. response = self.handle_exception(exc)
File "/Users/jian/phi/env/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
400. response = handler(request, *args, **kwargs)
File "/Users/jian/phi/backend/phi_catalogo/views.py" in put
148. if serializer.is_valid():
File "/Users/jian/phi/env/lib/python2.7/site-packages/rest_framework/serializers.py" in is_valid
550. return not self.errors
File "/Users/jian/phi/env/lib/python2.7/site-packages/rest_framework/serializers.py" in errors
542. ret = self.from_native(data, files)
File "/Users/jian/phi/env/lib/python2.7/site-packages/rest_framework/serializers.py" in from_native
375. return self.restore_object(attrs, instance=getattr(self, 'object', None))
File "/Users/jian/phi/env/lib/python2.7/site-packages/rest_framework/serializers.py" in restore_object
335. instance.update(attrs)
Exception Type: AttributeError at /publicarficha/1/
Exception Value: 'Fichas' object has no attribute 'update'
Try using a ModelSerializer instead of the Serializer as a super class.
I am building a website similar to a bartering website, but we are bartering Time,
I have a class Transaction, where it takes the "offer" value, deductions that value from the balance of the requesting user, and credits the value to the Offer'r.
Right now when I click on "Accept Offer" from my template I get this error
ofertoj_transaction.accepted_by may not be NULL
Stacktrace:
IntegrityError at /oferto/accept/
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/oferto/accept/?offer_id=1&creator=2
Django Version: 1.5.4
Python Version: 2.7.4
Installed Applications:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs',
'django.contrib.comments',
'django.contrib.sitemaps',
'zinnia',
'tagging',
'mptt',
'south',
'registration',
'blogs',
'turtle',
'ofertoj',
'petoj',
'x',
'profiles')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')
Traceback:
File "/home/talisman/virt_env/tempilo/local/lib/python2.7/site-packages/Django-1.5.4-py2.7.egg/django/core/handlers/base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "/home/talisman/virt_env/tempilo/local/lib/python2.7/site-packages/Django-1.5.4-py2.7.egg/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/home/talisman/virt_env/tempilo/local/lib/python2.7/site-packages/Django-1.5.4-py2.7.egg/django/views/generic/base.py" in dispatch
86. return handler(request, *args, **kwargs)
File "/home/talisman/projects/tempilo/ofertoj/views.py" in get
74. accepted_by=self.request.user.id
File "/home/talisman/projects/tempilo/ofertoj/models.py" in create
59. new_transaction.save()
File "/home/talisman/virt_env/tempilo/local/lib/python2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/models/base.py" in save
546. force_update=force_update, update_fields=update_fields)
File "/home/talisman/virt_env/tempilo/local/lib/python2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/models/base.py" in save_base
650. result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
File "/home/talisman/virt_env/tempilo/local/lib/python2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/models/manager.py" in _insert
215. return insert_query(self.model, objs, fields, **kwargs)
File "/home/talisman/virt_env/tempilo/local/lib/python2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/models/query.py" in insert_query
1675. return query.get_compiler(using=using).execute_sql(return_id)
File "/home/talisman/virt_env/tempilo/local/lib/python2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/models/sql/compiler.py" in execute_sql
937. cursor.execute(sql, params)
File "/home/talisman/virt_env/tempilo/local/lib/python2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/backends/util.py" in execute
41. return self.cursor.execute(sql, params)
File "/home/talisman/virt_env/tempilo/local/lib/python2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/backends/sqlite3/base.py" in execute
364. six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
File "/home/talisman/virt_env/tempilo/local/lib/python2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/backends/sqlite3/base.py" in execute
362. return Database.Cursor.execute(self, query, params)
Exception Type: IntegrityError at /oferto/accept/
Exception Value: ofertoj_transaction.accepted_by may not be NULL
part of ofertoj.views.py
class TransactionView(TemplateView, LoginRequiredMixin):
template_name = "ofertoj/offer_accepted.html"
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
if self.request.GET.get("offer_id"):
oferto = Oferto.objects.get(id=self.request.GET.get("offer_id"))
if oferto.valid:
transaction = Transaction()
transaction.create(
creator=self.request.GET.get("creator"),
amount=oferto.time,
accepted_by=self.request.user.id
)
acceptor = Profile.objects.get(user=self.request.user)
acceptor.balance = acceptor.balance - oferto.time
acceptor.save()
# credit the coins to the creator
creator = Profile.objects.get(user=oferto.user)
creator.balance = creator.balance + oferto.time
creator.save()
else:
return HttpResponse("This offer is already accepted")
else:
raise Http404
return self.render_to_response(context)
Part of Ofertoj.models
class Transaction(models.Model):
creator = models.IntegerField()
amount = models.IntegerField()
accepted_by = models.IntegerField()
def __unicode__(self):
return self.id
def create(self, **kwargs):
new_transaction = Transaction(
creator = kwargs['creator'],
amount = kwargs['amount'],
accepted_by = kwargs['accepted_by']
)
new_transaction.save()
return
this line is highlited in the stacktrace
acceptor = Profile.objects.get(user=self.request.user)
ofertoj.urls
url(
regex=r"^accept/$",
view = TransactionView.as_view(),
name = "accept_offer"
),
part of my template
{% if oferto.valid and not oferto.user == request.user %}
Accept this Offer
{% endif %}
<br /><br />
Your ofertoj application is trying to store a Transaction object which has an accepted_by field which is NULL but your database schema does not allow this field to be NULL.
Check this code:
transaction.create(
creator=self.request.GET.get("creator"),
amount=oferto.time,
accepted_by=self.request.user.id
)
and the code of transaction.create.
One possibility: if your user is not logged in then self.request.user.id will be None, and this translates to NULL in the database. I do not see anything in your code that requires the user to be logged in.
it was an issue with unicode method in the Profile model
and since, the balance was default null