我正在用 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
}
)