2

我正在用 django 创建一个艺术市场。我为配置文件设置了注册和自动创建信号。将在此应用程序上注册的用户分为三种类型:艺术家、赞助人和经纪人(我称之为 user_status。)我希望用户在注册表单上选择这三个字段之一。我已经到了注册表表单具有选择字段和选项并且用户可以选择一个并且表单保存以创建用户和配置文件的地步,但是当我进入管理员时配置文件没有选择的'user_status' .

我知道在注册时捆绑配置文件模型字段是非常不鼓励的,但我希望只选择这个字段,因为它会对站点如何查找用户产生重大影响。我已经读过(在这里),在注册时正确填写个人资料字段会涉及很多烦人的定制。这是真的?

我想如果有解决方案,它会在 Signals.py 上,但我不确定。

在signals.py中,当我输入:

user_status='Patron',

我可以用类似的东西替换“赞助人”instance.get('user_status')吗?我知道这里也有一些叫做“默认值”的东西,但我不熟悉。

用户/信号.py

from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile


@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:

        # This functions but cannot get it to grab the form chosen field from the user.
        # just default creates status as patron for now :(
        Profile.objects.update_or_create(
            user=instance,
            user_status='Patron',
        )


@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
    instance.profile.save()

用户/forms.py

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

from users.models import Profile

STATUS_CHOICES = (
    ('Artist', 'Artist'),
    ('Patron', 'Patron'),
    ('Broker', 'Broker')
)


class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()
    user_status = forms.ChoiceField(choices=STATUS_CHOICES)

    class Meta:
        model = User
        fields = ['username', 'email', 'user_status', 'password1', 'password2']

用户/views.py

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm


def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f'Hello {username}! Your account has been created. You are now ready to log in.')
            return redirect('login')
    else:
        form = UserRegisterForm()

    return render(request, 'users/register.html', {'form': form})


@login_required
def profile(request):
    return render(request, 'users/profile.html')

用户/模型.py

class Profile(models.Model):
    STATUS_CHOICES = (
        ('Artist', 'Artist'),
        ('Patron', 'Patron'),
        ('Broker', 'Broker')
    )
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    user_slug = models.SlugField(blank=True)
    image = models.ImageField(default='default.jpg', upload_to='profile_pics')
    user_status = models.CharField(max_length=100, choices=STATUS_CHOICES)

    def __str__(self):
        return f'{self.user.username} Profile'

反映第一条建议的编辑:

视图.py

def register(request):
    if request.method == 'POST':

        # create profile object but don't save it to db
        profile = ProfileSetupForm.save(request.POST)
        profile = profile_setup_form.save(commit=False)

        user_form = UserRegisterForm(request.POST)

        if user_form.is_valid():
            # create user object
            user = user_form.save(commit=False)
            # set profile attribute of user object
            user.profile = profile
            # save user - calls post_save
            user.save()

            username = user.username
            messages.success(request, f'Hello {username}! Your account has been created. You are now ready to log in.')
            return redirect('login')
    else:
        user_form = UserRegisterForm()
        profile_setup_form = ProfileSetupForm()

    return render(
        request,
        'users/register.html',
        {
            'user_form': user_form,
            'profile_setup_form': profile_setup_form
        }
    )

信号.py

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.update_or_create(
            user=instance,
            user_status=instance.profile.user_status,
        )

注册.html

{% extends "blog/base.html" %}
{% load crispy_forms_tags %}

{% block content %}
    <div class="content-section">
        <form method="POST">
            {% csrf_token %}
            <fieldset class="form-group">
                <legend class="border-bottom mb-4">Join Today</legend>
                {{ user_form|crispy }}
                {{ profile_setup_form|crispy }}
            </fieldset>
            <div class="form-group">
                <button class="btn btn-outline-info" type="submit">Sign Up</button>
            </div>
        </form>
        <div class="border-top pt-3">
            <small class="muted">
                Already have an account? <a class="ml-2" href="{% url 'login' %}">Sign In</a>
            </small>
        </div>
    </div>
{% endblock content %}

错误代码

Traceback (most recent call last):
  File "/Users/Tom/Desktop/art_project/art_env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Users/Tom/Desktop/art_project/art_env/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/Tom/Desktop/art_project/users/views.py", line 12, in register
    profile = ProfileSetupForm.save(user_status, request.POST)
  File "/Users/Tom/Desktop/art_project/art_env/lib/python3.8/site-packages/django/forms/models.py", line 451, in save
    if self.errors:

Exception Type: AttributeError at /register/
Exception Value: 'DeferredAttribute' object has no attribute 'errors'

如果我将“user_status”取出,这是错误代码,因此这是您建议的代码:

Traceback (most recent call last):
  File "/Users/Tom/Desktop/art_project/art_env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Users/Tom/Desktop/art_project/art_env/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/Tom/Desktop/art_project/users/views.py", line 12, in register
    profile = ProfileSetupForm.save(request.POST)
  File "/Users/Tom/Desktop/art_project/art_env/lib/python3.8/site-packages/django/forms/models.py", line 451, in save
    if self.errors:

Exception Type: AttributeError at /register/
Exception Value: 'QueryDict' object has no attribute 'errors'

调整forms.py文件

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

from users.models import Profile

STATUS_CHOICES = (
    ('Artist', 'Artist'),
    ('Patron', 'Patron'),
    ('Broker', 'Broker')
)


class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()
    # user_status = forms.ChoiceField(choices=STATUS_CHOICES)

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']


class ProfileSetupForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['user_status']

当前的views.py 文件,包含来自评论的调整

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm, ProfileSetupForm


def register(request):
    if request.method == 'POST':

        # create profile object but don't save it to db
        profile_setup_form = ProfileSetupForm.save(request.POST)
        profile = profile_setup_form.save(commit=False)

        user_form = UserRegisterForm(request.POST)

        if user_form.is_valid():
            # create user object
            user = user_form.save(commit=False)
            # set profile attribute of user object
            user.profile = profile
            # save user - calls post_save
            user.save()

            username = user.username
            messages.success(request, f'Hello {username}! Your account has been created. You are now ready to log in.')
            return redirect('login')
    else:
        user_form = UserRegisterForm()
        profile_setup_form = ProfileSetupForm()

    return render(
        request,
        'users/register.html',
        {
            'user_form': user_form,
            'profile_setup_form': profile_setup_form
        }
    )
4

1 回答 1

0

我会在您的注册页面上包含另一个表格,尽管这只是作为解决方案的建议。

forms.py

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

from user_status.models import Profile

STATUS_CHOICES = (
    ('Artist', 'Artist'),
    ('Patron', 'Patron'),
    ('Broker', 'Broker')
)


class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()
    # user_status = forms.ChoiceField(choices=STATUS_CHOICES)

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']


class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['user_status']

views.py

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm, ProfileForm


def register(request):
    if request.method == 'POST':

        # create profile object but don't save it to db
        profile_form = ProfileForm(request.POST)
        profile = profile_form.save(commit=False)

        user_form = UserRegisterForm(request.POST)

        if user_form.is_valid():
            # create user object
            user = user_form.save(commit=False)
            # set profile attribute of user object
            user.profile = profile
            # save user - calls post_save
            user.save()
            
            username = user.username
            messages.success(request, f'Hello {username}! Your account has been created. You are now ready to log in.')
            return redirect('login')
    else:
        user_form = UserRegisterForm()
        profile_form = ProfileForm()


    return render(
        request, 
        'users/register.html', 
        {
            'user_form': user_form,
            'profile_form': profile_form
        }
    )


@login_required
def profile(request):
    return render(request, 'users/profile.html')

signals.py

from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile


@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:

        # can now set user_status attribute
        Profile.objects.update_or_create(
            user=instance,
            user_status=instance.profile.user_status,
        )


@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
    instance.profile.save()

我不知道您的register.html页面是什么样的,但您会以以下方式显示这些表单作为示例。

register.html

<h1>Registration Page</h1>

<form action="/register" method="POST">
    {% csrf_token %}

    {{ user_form.as_p }}

    {{ profile_form.as_p }}

    <input type="submit" value="Register"></input>
</form>

您可以在 profile_form 中包含更多字段,例如用户的图像,如果您想让他们在注册期间也包含这些字段。

于 2021-02-05T02:25:15.393 回答