我有一个正在处理的小项目,并且有一个处理交货地址的模型。我希望能够在此表单上设置/更新用户详细信息,但我真的不确定如何做到这一点。
我试图在我的Profile模型上将一个用户设置为与User的OneoToOneField,但这似乎不起作用,并且出现错误:
Exception Value:
Cannot assign "<User: bill>": "Profile.user" must be a "User" instance.
不确定如何进行。
我的模特是:
from django.db import models
from django.contrib.auth.models import User
from django.contrib import auth
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
# Create your models here.
class User(auth.models.User, auth.models.PermissionsMixin):
def __str__(self):
return "@{}".format(self.username)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
houseNumber = models.CharField(max_length=150, default='')
street = models.CharField(max_length=150, default='')
suberb = models.CharField(max_length=150, default='')
city = models.CharField(max_length=150, default='')
phone = models.CharField(max_length=150, default='')
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
我的看法是:
class ProfileView(LoginRequiredMixin,FormView):
template_name = 'profile_form.html'
success = 'profile.html'
form_class = ProfileForm
# def get_context_data(self, **kwargs):
# context = super(ProfileView, self).get_context_data(**kwargs)
# context['now'] = timezone.now()
# return context
def form_valid(self, form):
form.instance.created_by = self.request.user
return super().form_valid(form)
def get(self, request, *args, **kwargs):
form = self.form_class(initial=self.initial)
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
profile = form.save(commit=False)
profile.user = User.objects.get(pk=request.user.pk)
profile.save()
return HttpResponseRedirect(reverse('profile_details', args=(post.id,)))
print("test")
return render(request, self.template_name, {'form': form})
我期望用户会链接到收货地址。我该怎么办?
我得到的一些异常如下:
Internal Server Error: /accounts/profile/
Traceback (most recent call last):
File "C:\Users\009028\Envs\mydjangoproject\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\009028\Envs\mydjangoproject\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\009028\Envs\mydjangoproject\lib\site-packages\django\core\handlers\base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\009028\Envs\mydjangoproject\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\009028\Envs\mydjangoproject\lib\site-packages\django\contrib\auth\mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "C:\Users\009028\Envs\mydjangoproject\lib\site-packages\django\views\generic\base.py", line 88, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\009028\Documents\django-projects\aurion\burger\accounts\views.py", line 40, in post
profile.user = request.user
File "C:\Users\009028\Envs\mydjangoproject\lib\site-packages\django\db\models\fields\related_descriptors.py", line 300, in __set__
super().__set__(instance, value)
File "C:\Users\009028\Envs\mydjangoproject\lib\site-packages\django\db\models\fields\related_descriptors.py", line 210, in __set__
self.field.remote_field.model._meta.object_name,
ValueError: Cannot assign "<SimpleLazyObject: <User: bill>>": "Profile.user" must be a "User" instance.
[17/Apr/2019 16:12:05] "POST /accounts/profile/ HTTP/1.1" 500 97063
答案 0 :(得分:0)
您可以只使用 request.user
,然后您会得到 current logged in user
profile = form.save(commit=False)
profile.user = request.user
profile.save()
用于调试可以 print(request.user)
答案 1 :(得分:0)
如我所见,创建用户时,有一个signal用于创建配置文件。您可以将这些信号放入signals.py
中,并在应用就绪时将其导入。例如:
# assuming they are in apps_directory/profile/signals.py
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
# apps.py
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
class ProfilesConfig(AppConfig):
name = 'profiles'
verbose_name = _('profiles')
def ready(self):
import apps_directory.profiles.signals
现在,如果您想更新已经通过信号创建的配置文件,则可以使用UpdateView:
class ProfileUpdateView(LoginRequiredMixin, UpdateView):
template_name = 'profile_form.html'
success = 'profile'
model = Profile
form_class = ProfileForm # assuming its a modelform
def get_object(self):
return self.request.user.profile # we will get profile as it has onetoone relation to user model
答案 2 :(得分:0)
request.user
不是您的自定义User
的实例,它是django.contrib.auth.models.User
由于您定义了自己的User
模型,因此需要告诉Django这是用于settings.py
中的身份验证的模型。
#settings.py
AUTH_USER_MODEL = 'myapp.User' #point to the app in whose model.py, User is defined