Как связать аутентифицированного пользователя с formModel - PullRequest
0 голосов
/ 17 апреля 2019

У меня есть небольшой проект, над которым я работаю, и у меня есть Модель, которая имеет дело с адресом доставки.Я хочу иметь возможность устанавливать / обновлять данные пользователя в этой форме, но я действительно не уверен, как это сделать.

Я пытался установить пользователя в моей модели профиля как OneoToOneField with User, но это не похожена работу, и если я получаю сообщение об ошибке:

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 голосов
/ 17 апреля 2019

Как я вижу, существует сигнал для создания профиля при создании пользователя.Вы можете поместить эти сигналы в 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
0 голосов
/ 17 апреля 2019

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
0 голосов
/ 17 апреля 2019

вы можете просто использовать request.user, тогда вы получите current logged in user

profile = form.save(commit=False)
profile.user = request.user
profile.save()

для отладочной банки print(request.user)

...