python - 在 Django 中为预注册用户创建用户帐户
问题描述
我有一个网站,它有一个注册系统和一个有一些注册用户的博客。昨天,我添加了一个新应用程序,为每个用户创建专用的个人资料页面。
问题是,没有为已经注册的用户创建个人资料页面。我猜这是因为用户配置文件创建逻辑仅允许在用户注册后创建配置文件。
下面是我的models.py中的代码
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=User)
def create_account(sender, instance, created, *args, **kwargs):
if created:
profile, new = UserAccount.objects.get_or_create(user=instance)
post_save.connect(create_account, sender=settings.AUTH_USER_MODEL)
那么,我可以做些什么来创建这些个人资料页面?
我尝试了以下方法:
1. 针对每个注册用户的用户名手动创建个人资料页面。(但这不是我想依靠的方式。这只是一个临时安排)
与此相关的问题是,当创建这些个人资料页面的超级用户调用他的私人个人资料页面 [at /u/] 时,代码会查看由超级用户而不是他自己创建的所有用户。
这是显示的错误:
MultipleObjectsReturned at /u/
get() returned more than one UserAccount -- it returned 2!
.
.
.
instance = get_object_or_404(UserAccount)
那么,这里的代码有什么问题?[我的意见.py]
# public user profile
def user_account(request, username):
instance = get_object_or_404(UserAccount, user__username=username)
context = {
'instance' : instance,
'title' : "User Account",
}
template = "user_accounts/public_account.html"
return render(request, template, context)
# private user profile.
@login_required
def self_user_account(request):
if not request.user.is_authenticated:
raise Http404
instance = get_object_or_404(UserAccount)
if not request.user == instance.user:
raise Http404
context = {
'instance' : instance,
'title' : 'Your Account',
}
template = "user_accounts/self_account.html"
return render(request, template, context)
# ability to update the user profile
@login_required
def update_user_account(request):
if not request.user.is_authenticated:
raise Http404
instance = get_object_or_404(UserAccount)
if not request.user == instance.user:
raise Http404
if request.method == 'POST':
form = UserAccountForm(request.POST or None, request.FILES or None, instance=instance)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
messages.success(request, "Account Updated.")
return HttpResponseRedirect("/u/")
else:
messages.error(request, "Something went wrong. Profile not created.")
else:
form = UserAccountForm(instance=instance)
context = {
'title': 'Update Your Account',
'form' : form,
}
template = "user_accounts/update.html"
return render(request, template, context)
下面是我的urls.py这些是在主urls.py的 /u/ 之后填充的
urlpatterns = [
# for updating
url(r'^update/$', views.update_user_account, name="update_user_account"),
# for outside world
url(r'^(?P<username>[\w.@+-]+)/$', views.user_account, name="public_user_account"),
# for the user himself
url(r'^$', views.self_user_account, name="self_user_account"),
]
下面是我的models.py脚本
# uploading profile photos
def upload_location(instance, filename):
return "account_photos/%s/%s" %(instance.user, filename)
# Create your models here.
class UserAccount(models.Model):
user = models.OneToOneField(User)
photo = models.ImageField(
upload_to=upload_location, # there needs to be a upload location tho
# most probably a cdn server
blank=True,
null=True,
width_field="width_field",
height_field="height_field")
width_field = models.IntegerField(default=0, null=True)
height_field = models.IntegerField(default=0, null=True)
bio = models.TextField(max_length=60, null=True, blank=True, verbose_name="You in 60 words.")
phone = PhoneNumberField(blank=True, verbose_name="Contact Number")
status = models.CharField(max_length=128, default="Student")
totos = models.IntegerField(default=0, verbose_name="Contribution")
user_since = models.DateTimeField(auto_now=True)
# social links
email = models.EmailField(verbose_name="email address",
max_length=255,
unique=True,
null=True, blank=True)
custom_link = models.URLField(null=True, blank=True)
facebook_link = models.URLField(null=True, blank=True)
twitter_link = models.URLField(null=True, blank=True)
linkedin_link = models.URLField(null=True, blank=True)
github_link = models.URLField(null=True, blank=True)
reddit_link = models.URLField(null=True, blank=True)
def __str__(self):
return self.user.username
def get_absolute_url(self):
return self.reverse("accounts:public_user_account", kwargs={"username":self.user__username})
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=User) # User is coming from the user=models.OneToOneField(<User>)
def create_account(sender, instance, created, *args, **kwargs):
if created:
profile, new = UserAccount.objects.get_or_create(user=instance)
post_save.connect(create_account, sender=settings.AUTH_USER_MODEL)
解决方案
使用get_object_or_404(UserAccount)
使用所有用户帐户,因此MultipleObjectsReturned
如果存在多个用户帐户,则会出错。
您需要过滤查询集,使其仅返回一个对象。您已经在使用用户名来执行此操作。只要用户名是唯一的并且每个用户只有一个用户帐户,这应该可以工作。
get_object_or_404(UserAccount, user__username=username)
如果要过滤登录用户,可以执行以下操作:
get_object_or_404(UserAccount, user=request.user)
或者,根据您的模型,您可能能够向后跟踪一对一字段,例如:
instance = request.user.useraccount
推荐阅读
- google-tag-manager - 我应该使用工作箱运行时缓存 staleWhileRevalidate 来缓存 gtm.js 吗?
- javascript - 播放多个音轨
- node.js - 如何返回无效缓冲区以测试 API 调用?
- javascript - 如何创建文本通道
- python - Z3 Solver() 中的约束大小
- javascript - Select2 下拉问题。如何将日期选择器中的日期填充到 select2 下拉列表中?
- python - 识别超过 N 行的 10 分钟窗口
- javascript - 如何在 Electron 应用程序的加载时间内防止光标上的沙漏?
- docker - 如何在高山容器中安装 Docker?
- python - 将字符串安全地转换为元组列表中的整数