Django all-auth中如何从User模型获取谷歌登录用户的用户名
解决方法
第一步:修正视图代码
当前视图存在变量未定义问题,你查询得到的积分排名结果变量名为points,但上下文里用了不存在的result,同时上下文key命名为user容易和Django内置的全局user变量冲突,修正后的代码如下:
def leaderBoard(request): points = Points.objects.all().order_by("-score") # 改名为points_list更符合语义 context = {"points_list": points} return render(request, "Main/lb.html", context)
第二步:修正模板取值逻辑
你遍历的每一项是Points模型实例,需要先通过外键user拿到关联的Django User对象,再调用allauth提供的社交账户属性获取谷歌用户名,同时兼容非谷歌登录的用户,修正后的模板代码如下:
<div class="leaderboard-table"> {% for point_item in points_list %} <div class="board-item"> <div>{{ forloop.counter }}</div> <!-- 用forloop.counter自动生成排名,替代写死的1 --> <div> {% with social_account=point_item.user.socialaccount_set.first %} {% if social_account %} <img src="{{ social_account.get_avatar_url }}" alt="用户头像" /> <!-- 两种方式获取谷歌用户名,二选一即可 --> <!-- 方式1:从extra_data直接取 --> {{ social_account.extra_data.name }} <!-- 方式2:用allauth封装的方法,适配更多第三方登录场景 --> <!-- {{ social_account.get_provider_account.to_str }} --> {% else %} <!-- 兼容普通账号登录的用户,显示Django User默认的用户名 --> {{ point_item.user.username }} {% endif %} {% endwith %} </div> <div>Test's Taken - 30</div> <div>{{ point_item.score }} Points</div> </div> {% endfor %} </div>
可选优化
如果不想在模板里写过长的链式调用,可以在Points模型中新增自定义方法,封装用户名获取逻辑,让模板代码更简洁:
class Points(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) score = models.BigIntegerField() def get_display_name(self): social_account = self.user.socialaccount_set.first() if social_account: return social_account.extra_data.get("name", self.user.username) return self.user.username
之后模板里直接调用{{ point_item.get_display_name }}即可。
内容的提问来源于stack exchange,提问作者santosh
相关产品推荐
相关产品推荐

