AttributeError'IdLookup'对象没有属性'rel'

时间:2013-11-01 13:21:36

标签: rest serialization django-models attributeerror neo4django

我尝试使用django REST框架的教程http://django-rest-framework.org/#django-rest-framework来管理用户。 (我还使用Neo4j数据库和neo4django映射器https://github.com/scholrly/neo4django通过python访问数据。)
无论如何,我称之为localhost:8000 / users会出现AttributeError。

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服务领域的新手。我希望有人可以提供帮助。提前谢谢。

1 个答案:

答案 0 :(得分:2)

首先,我建议使用Tastypie - neo4django支持的开箱即用 - 代替Django Rest Framework - 或使用Django Rest Framework Serializer而不是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一起使用会更好。 这是Matt Luongo(或Lukas Martini?)https://gist.github.com/mhluongo/5789513

的要点

TIP。 Serializer中的Django Rest Framework位于Resource中的Tastypie,并始终确保您使用的是neo4django(pip install -e git+https://github.com/scholrly/neo4django/#egg=neo4django)的github版本