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
Related
I get an error when I login http://127.0.0.1:8000/admin.
I don't know where the error occurred.
This is the error message:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/admin/login/?next=/admin/
Django Version: 2.0.5
Python Version: 3.6.2
Installed Applications:
['users',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles']
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/c/Softwares/anaconda3/envs/medic/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "/home/c/Softwares/anaconda3/envs/medic/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "/home/c/Softwares/anaconda3/envs/medic/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/c/Softwares/anaconda3/envs/medic/lib/python3.6/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
44. response = view_func(request, *args, **kwargs)
File "/home/c/Softwares/anaconda3/envs/medic/lib/python3.6/site-packages/django/contrib/admin/sites.py" in login
382. self.each_context(request),
File "/home/c/Softwares/anaconda3/envs/medic/lib/python3.6/site-packages/django/contrib/admin/sites.py" in each_context
302. 'available_apps': self.get_app_list(request),
File "/home/c/Softwares/anaconda3/envs/medic/lib/python3.6/site-packages/django/contrib/admin/sites.py" in get_app_list
470. app_dict = self._build_app_dict(request)
File "/home/c/Softwares/anaconda3/envs/medic/lib/python3.6/site-packages/django/contrib/admin/sites.py" in _build_app_dict
418. has_module_perms = model_admin.has_module_permission(request)
File "/home/c/Softwares/anaconda3/envs/medic/lib/python3.6/site-packages/django/contrib/admin/options.py" in has_module_permission
506. return request.user.has_module_perms(self.opts.app_label)
File "/home/c/Softwares/anaconda3/envs/medic/lib/python3.6/site-packages/django/contrib/auth/models.py" in has_module_perms
422. return _user_has_module_perms(self, module)
File "/home/c/Softwares/anaconda3/envs/medic/lib/python3.6/site-packages/django/contrib/auth/models.py" in _user_has_module_perms
196. if backend.has_module_perms(user, app_label):
Exception Type: TypeError at /admin/login/
Exception Value: has_module_perms() takes 2 positional arguments but 3 were given
users/views.py:
from django.shortcuts import render, redirect
from .forms import RegisterForm
# Create your views here.
def index(request):
return render(request, 'index.html')
def register(request):
redirect_to = request.POST.get('next', request.GET.get('next', ''))
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
form.save()
if redirect_to:
return redirect(redirect_to)
else:
return redirect('/')
else:
form = RegisterForm()
return render(request, 'users/register.html', context={'form': form, 'next': redirect_to})
this is a user login registration authentication code, and only have user app.
in the traceback seem the error didn't occured in my code, so i don't know where it is wrong.
user/models.py:
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class User(AbstractUser):
email = models.EmailField(verbose_name='email',
unique=True, error_messages={'unique': 'Email is already occupied'})
class Meta(AbstractUser.Meta):
pass
If use an AbstractBaseUser add arguments, or try overwriting the function, can use this:
def has_module_perms(self, *args): # or add
# ....
return True
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.
I am using Django User model for one of the select field.
However i am not able to pass only users linked to a commmon organisation/company.
I have a onetoone profile linking for each user. This one to onetoone model is again linked to organisation model.
Now need a form where select field should have users linked to organisation model.
Here is my form.py:
class taskaddform(forms.ModelForm):
def __init__(self,user, *args, **kwargs):
self.user = kwargs.pop('user', None)
self.request = kwargs.pop('request', None)
super(taskaddform, self).__init__(*args, **kwargs)
self.fields["assigned_to"].queryset=User.objects.filter(company=self.request.user.company.entity)
class Meta:
model=tasktable
fields=('task','assigned_to','discription','documents',)
views.py:
#login_required
def taskadd(request):
if request.method=='POST':
form=taskaddform(request.POST,request.FILES,request.user)
if form.is_valid():
new_form=form.save(commit=False)
new_form.created_by=request.user
new_form.company=request.user.company.entity
new_form.save()
return HttpResponseRedirect(reverse('taskadd'),messages.add_message(request, messages.SUCCESS,'Task added succesfully.'))
else:
form=taskaddform(request.user)
return render(request,'taskadd.html',{'form':form})
Error Log:
Request Method: GET
Request URL: http://127.0.0.1:8000/task/taskadd/
Django Version: 1.10
Exception Type: AttributeError
Exception Value:
'NoneType' object has no attribute 'user'
traceback:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/task/taskadd/
Django Version: 1.10
Python Version: 2.7.10
Installed Applications:
('invoice',
'support',
'task',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'widget_tweaks')
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',
'django.middleware.security.SecurityMiddleware')
Traceback:
File "/Library/Python/2.7/site-packages/django/core/handlers/exception.py" in inner
39. response = get_response(request)
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in _legacy_get_response
249. response = self._get_response(request)
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
23. return view_func(request, *args, **kwargs)
File "/Users/pulkitsharma/Documents/workspace1/tiktant/task/views.py" in taskadd
38. form=taskaddform(request.user)
File "/Users/pulkitsharma/Documents/workspace1/tiktant/task/forms.py" in __init__
11. self.fields["assigned_to"].queryset=User.objects.filter(company=self.request.user.company.entity)
Exception Type: AttributeError at /task/taskadd/
Exception Value: 'NoneType' object has no attribute 'user'
Updated views.py.
#login_required
def taskadd(request):
if request.method=='POST':
form=taskaddform(request, request.POST,request.FILES,request.user)
if form.is_valid():
new_form=form.save(commit=False)
new_form.created_by=request.user
new_form.company=request.user.company.entity
new_form.save()
return HttpResponseRedirect(reverse('taskadd'),messages.add_message(request, messages.SUCCESS,'Task added succesfully.'))
else:
form=taskaddform(request)
return render(request,'taskadd.html',{'form':form})
and in your forms.py --
class taskaddform(forms.ModelForm):
def __init__(self, request, *args, **kwargs):
self.request = request
super(taskaddform, self).__init__(request, *args, **kwargs)
self.fields["assigned_to"].queryset=User.objects.filter(company=self.request.user.company.entity)
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 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