如何将经过身份验证的用户链接到formModel

时间:2019-04-17 05:39:41

标签: python django django-models

我有一个正在处理的小项目,并且有一个处理交货地址的模型。我希望能够在此表单上设置/更新用户详细信息,但我真的不确定如何做到这一点。

我试图在我的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

3 个答案:

答案 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