1

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

模型.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']

序列化程序.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')

视图.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 服务领域比较陌生。我希望有人能帮忙。提前致谢。

4

1 回答 1

2

首先,我建议使用Tastypie- 开箱即用的neo4django- 而不是Django Rest Framework- 或使用Django Rest Framework Serializer而不是ModelSerializeror (我认为最糟糕的选择)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)

但我仍然认为使用Tastypiewith更好ModelResource。这是 Matt Luongo(或 Lukas Martini ?)的要点https://gist.github.com/mhluongo/5789513

小费。在哪里,Serializer在哪里,并始终确保您使用的是 github 版本的 neo4django ( )Django Rest FrameworkResourceTastypiepip install -e git+https://github.com/scholrly/neo4django/#egg=neo4django

于 2013-11-03T17:54:59.127 回答