使用django-socialregistration从Facebook获取名字

2 投票
2 回答
949 浏览
提问于 2025-04-17 08:56

使用 django-socialregistration 这个库,我想在用户通过 Facebook 登录时获取他们的名字。

我尝试在 django-socialregistration/views.py 文件中添加以下几行代码:

graph = request.facebook.graph 
fb_profile = graph.get_object("me")
user.first_name = fb_profile['first_name']
user.save()

我把这些代码放在 post(self, request) 方法中,紧接着 user = profile.authenticate() 之后,但当我尝试连接时却出现了这个错误:

int() argument must be a string or a number, not 'AnonymousUser'

这是为什么呢?错误发生在第一行 graph = request.facebook.graph

这是 django-socialregistration 视图的代码:

class Setup(SocialRegistration, View):
    """
    Setup view to create new Django users from third party APIs.
    """
    template_name = 'socialregistration/setup.html'

    def get_form(self):
        """
        Return the form to be used. The return form is controlled
        with ``SOCIALREGISTRATION_SETUP_FORM``.
        """
        return self.import_attribute(FORM_CLASS)

    def get_username_function(self):
        """
        Return a function that can generate a username. The function
        is controlled with ``SOCIALREGISTRATION_GENERATE_USERNAME_FUNCTION``.
        """
        return self.import_attribute(USERNAME_FUNCTION)

    def get_initial_data(self, request, user, profile, client):
        """
        Return initial data for the setup form. The function can be
        controlled with ``SOCIALREGISTRATION_INITIAL_DATA_FUNCTION``.

        :param request: The current request object
        :param user: The unsaved user object
        :param profile: The unsaved profile object
        :param client: The API client
        """
        if INITAL_DATA_FUNCTION:
            func = self.import_attribute(INITAL_DATA_FUNCTION)
            return func(request, user, profile, client)
        return {}

    def generate_username_and_redirect(self, request, user, profile, client):
        """
        Generate a username and then redirect the user to the correct place.
        This method is called when ``SOCIALREGISTRATION_GENERATE_USERNAME``
        is set.

        :param request: The current request object
        :param user: The unsaved user object
        :param profile: The unsaved profile object
        :param client: The API client
        """
        func = self.get_username_function()

        user.username = func(user, profile, client)
        user.save()

        profile.user = user
        profile.save()

        user = profile.authenticate()

        self.send_connect_signal(request, user, profile, client)

        self.login(request, user)

        self.send_login_signal(request, user, profile, client)

        self.delete_session_data(request)

        return HttpResponseRedirect(self.get_next(request))

    def get(self, request):
        """
        When signing a new user up - either display a setup form, or
        generate the username automatically.
        """
        # I want some validation here, hacked up in the generic callback
        try:
            urlfrom = request.session['urlfrom']
            match = resolve(urlfrom)
            username, code = match.args
            checkcode, referrer, ticket = utils.register_validate(username, code)
        except:
            return http.HttpResponseServerError()
        # validation end

        try:
            user, profile, client = self.get_session_data(request)
        except KeyError:
            return self.render_to_response(dict(
                error=_("Social profile is missing from your session.")))

        if GENERATE_USERNAME:
            return self.generate_username_and_redirect(request, user, profile, client)

        form = self.get_form()(initial=self.get_initial_data(request, user, profile, client))

        return self.render_to_response(dict(form=form))

    def post(self, request):
        """
        Save the user and profile, login and send the right signals.
        """
        try:
            user, profile, client = self.get_session_data(request)
        except KeyError:
            return self.render_to_response(dict(
                error=_("A social profile is missing from your session.")))

        form = self.get_form()(request.POST, request.FILES,
            initial=self.get_initial_data(request, user, profile, client))

        if not form.is_valid():
            return self.render_to_response(dict(form=form))

        user, profile = form.save(request, user, profile, client)

        # validation count up referrals, tickets, etc.
        try:
            urlfrom = request.session['urlfrom']
            match = resolve(urlfrom)
            username, code = match.args
            checkcode, referrer, ticket = utils.register_validate(username, code)
        except:
            return http.HttpResponseServerError()
        utils.register_accounting(checkcode, referrer, ticket, user)

        user = profile.authenticate()

        self.send_connect_signal(request, user, profile, client)

        self.login(request, user)

        self.send_login_signal(request, user, profile, client)

        self.delete_session_data(request)

        # added by me
        graph = request.facebook.graph 
        fb_profile = graph.get_object("me")
        user.first_name = fb_profile['first_name']
        user.save()
        #

        return HttpResponseRedirect(self.get_next(request))

2 个回答

1

看起来你在访问 request.facebook.graph 时,可能会遇到一个叫做 AnonymousUser 的对象在 request.user 中。你可以检查一下你的用户是否 已认证(关于 匿名用户 的更多信息):

request.user.is_authenticated()

另一个可以尝试的工具是 pdb,你可以在开发服务器中使用它(通过 manage.py runserver 启动)。使用它最简单的方法是,在你的代码出错之前,加上这一行代码来设置一个断点:

import pdb; pdb.set_trace()

这样你就可以在提示符下查看变量的状态和上下文了。

1

让我来试着解释一下。从你的代码来看,在这行代码的上面,你正在删除会话数据 self.delete_session_data(request)。这可能会导致会话密钥或者认证令牌被删除。你可以试着把你的代码放在那行代码的下面。

撰写回答