2013-11-01 29 views
1

我嘗試使用django REST框架的教程http://django-rest-framework.org/#django-rest-framework來管理用戶。 (我也使用Neo4j數據庫和neo4django映射器https://github.com/scholrly/neo4django通過python訪問數據。)
無論如何,我打電話給本地主機:8000 /用戶出現一個AttributeError。AttributeError'IdLookup'對象沒有'rel'屬性

models.py

from django.utils import timezone 
from django.conf import settings 

from django.contrib.auth import models as django_auth_models 

from ..db import models 
from ..db.models.manager import NodeModelManager 
from ..decorators import borrows_methods 

class UserManager(NodeModelManager, django_auth_models.UserManager): 
    pass 

# all non-overriden methods of DjangoUser are called this way instead. 
# inheritance would be preferred, but isn't an option because of conflicting 
# metaclasses and weird class side-effects 
USER_PASSTHROUGH_METHODS = (
    "__unicode__", "natural_key", "get_absolute_url", 
    "is_anonymous", "is_authenticated", "get_full_name", "set_password", 
    "check_password", "set_unusable_password", "has_usable_password", 
    "get_group_permissions", "get_all_permissions", "has_perm", "has_perms", 
    "has_module_perms", "email_user", 'get_profile','get_username') 

@borrows_methods(django_auth_models.User, USER_PASSTHROUGH_METHODS) 
class User(models.NodeModel): 
    objects = UserManager() 

    username = models.StringProperty(indexed=True, unique=True) 
    first_name = models.StringProperty() 
    last_name = models.StringProperty() 

    email = models.EmailProperty(indexed=True) 
    password = models.StringProperty() 

    is_staff = models.BooleanProperty(default=False) 
    is_active = models.BooleanProperty(default=False) 
    is_superuser = models.BooleanProperty(default=False) 

    last_login = models.DateTimeProperty(default=timezone.now()) 
    date_joined = models.DateTimeProperty(default=timezone.now()) 

    USERNAME_FIELD = 'username' 
    REQUIRED_FIELDS=['email'] 

serializers.py

from neo4django.graph_auth.models import User 
from rest_framework import serializers 


class UserSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = User 
     fields = ('url', 'username', 'email') 

views.py

from neo4django.graph_auth.models import User 
from rest_framework import viewsets 

from api.serializers import UserSerializer 

class UserViewSet(viewsets.ModelViewSet): 
    """ 
    API endpoint that allows users to be viewed or edited. 
    """ 
    queryset = User.objects.all() 
    serializer_class = UserSerializer 

我得到這個:

Environment: 

Request Method: GET 
Request URL: http://localhost:8000/users/ 

Django Version: 1.5.3 
Python Version: 2.7.3 
Installed Applications: 
('core.models', 
'django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'neo4django.graph_auth', 
'rest_framework') 
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') 


Traceback: 
File "/opt/phaidra/env/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response 
    115.       response = callback(request, *callback_args, **callback_kwargs) 
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/viewsets.py" in view 
    78.    return self.dispatch(request, *args, **kwargs) 
File "/opt/phaidra/env/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view 
    77.   return view_func(*args, **kwargs) 
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch 
    399.    response = self.handle_exception(exc) 
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch 
    396.    response = handler(request, *args, **kwargs) 
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/mixins.py" in list 
    92.    serializer = self.get_pagination_serializer(page) 
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/generics.py" in get_pagination_serializer 
    113.   return pagination_serializer_class(instance=page, context=context) 
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/pagination.py" in __init__ 
    85.   self.fields[results_field] = object_serializer(source='object_list', **context_kwarg) 
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/serializers.py" in __init__ 
    162.   self.fields = self.get_fields() 
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/serializers.py" in get_fields 
    198.   default_fields = self.get_default_fields() 
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/serializers.py" in get_default_fields 
    599.   while pk_field.rel and pk_field.rel.parent_link: 

Exception Type: AttributeError at /users/ 
Exception Value: 'IdLookup' object has no attribute 'rel' 

我在Python/Django/REST服務領域頗爲新穎。我希望有人能幫忙。提前致謝。

回答

2

首先,我建議要麼使用Tastypie - 這是由出支持neo4django盒子 - 而不是Django Rest Framework - 或使用Django Rest FrameworkSerializer代替ModelSerializer或(在我看來,最糟糕的選擇)HyperlinkedModelSerializer

至於你得到的錯誤,問題是neo4django不返回記錄ID,因此你得到的錯誤。

一個解決方案是覆蓋restore_object函數,就像這樣,包含該ID。

# User Serializer 
class UserSerializer(serializers.Serializer): 
    id = serializers.IntegerField() 
    username = serializers.CharField(max_length=30) 
    first_name = serializers.CharField(max_length=30) 
    last_name = serializers.CharField(max_length=30) 

    email = serializers.EmailField() 
    password = serializers.CharField(max_length=128) 

    is_staff = serializers.BooleanField() 
    is_active = serializers.BooleanField() 
    is_superuser = serializers.BooleanField() 

    last_login = serializers.DateTimeField() 
    date_joined = serializers.DateTimeField() 

    def restore_object(self, attrs, instance=None): 
     """ 
     Given a dictionary of deserialized field values, either update 
     an existing model instance, or create a new model instance. 
     """ 
     if instance is not None: 
      instance.id = attrs.get('ID', instance.pk) 
      instance.username = attrs.get('Username', instance.username) 
      instance.first_name = attrs.get('First Name', instance.first_name) 
      instance.last_name = attrs.get('First Name', instance.last_name) 
      instance.email = attrs.get('email', instance.email) 
      instance.password = attrs.get('Password', instance.password) 
      instance.is_staff = attrs.get('Staff', instance.is_staff) 
      instance.is_active = attrs.get('Active', instance.is_active) 
      instance.is_superuser = attrs.get('Superusers', instance.is_superuser) 
      instance.last_login = attrs.get('Last Seen', instance.last_login) 
      instance.date_joined = attrs.get('Joined', instance.date_joined) 
      return instance 
     return User(**attrs) 

但我仍然認爲這是更好地使用TastypieModelResource。 這是馬特Luongo(或盧卡斯馬提尼?)的要點https://gist.github.com/mhluongo/5789513

提示。凡SerializerDjango Rest Framework,在TastypieResource,並始終確保您使用neo4django GitHub的版本(pip install -e git+https://github.com/scholrly/neo4django/#egg=neo4django

+0

非常感謝。我們轉向了Tastypie。它立即工作! – user2944695