Django:在模型表单中使用 ImageField
Django: Use ImageField in Modelforms
所以我有这个模型形式:
User = get_user_model()
class UserRegisterForm(forms.ModelForm):
username = forms.CharField(label='', widget=forms.TextInput(attrs={'placeholder': 'Username'}))
email = forms.EmailField(label='', widget=forms.TextInput(attrs={'placeholder': 'Email Address'}))
email2 = forms.EmailField(label='', widget=forms.TextInput(attrs={'placeholder': 'Confirm Email'}))
password = forms.CharField(label='', widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
avatar = forms.ImageField(upload_to='profile_images')
class Meta:
model = User
fields = [
'username',
'email',
'email2',
'password'
]
但是这个出现
TypeError: __init__() got an unexpected keyword argument 'upload_to'
问题是,如果我将 ImageField 对象添加到模型中,我认为它会起作用,但我没有模型,如您所见,我正在使用 get_user_model(),是否有在模型表单中使用 upload_to 的方法,或者我如何添加到默认的 'get_user_model' ImageField 对象?
你应该制作一个额外的模型来存储头像,或者你可以制作一个custom user model。
如果你制作一个额外的模型,例如Profile
,你可以将其定义为:
# app/models.py
from django.conf import settings
from django.db import models
class Profile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
editable=False
)
avatar = models.ImageField(upload_to='profile_images/')
然后你可以做两个ModelForm
例如。事实上,对于 User
,您最好使用 UserCreationForm
[Django-doc],因为它已经实现了验证密码是否匹配的逻辑,并且它还会透明地散列密码。
因此,您可以为 Profile
定义一个 ModelForm
,并使用:
# app/forms.py
from django import forms
from app.models import Profile
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['avatar']
在视图中,您可以使用两种形式:
# app/views.py
from app.forms import ProfileForm
from django.contrib.auth.forms import UserCreationForm
def some_view(request):
if request.method == 'POST':
form = UserCreationForm(request.POST, request.FILES)
form2 = ProfileForm(request.POST, request.FILES)
if form.is_valid() and form2.is_valid():
user = form.save()
form2<b>.instance.user = user</b>
form2.save()
return redirect(<i>'name-of-some-other-view'</i>)
else:
form = UserCreationForm()
form2 = ProfileForm()
return render(request, <i>'name-of-some-template.html'</i>, {'form': form, 'form2': form2})
因此您在同一个 <form>
标签中呈现两种形式:
<form action="{% url 'some_view' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ <b>form</b> }}
{{ <b>form2</b> }}
</form>
所以我有这个模型形式:
User = get_user_model()
class UserRegisterForm(forms.ModelForm):
username = forms.CharField(label='', widget=forms.TextInput(attrs={'placeholder': 'Username'}))
email = forms.EmailField(label='', widget=forms.TextInput(attrs={'placeholder': 'Email Address'}))
email2 = forms.EmailField(label='', widget=forms.TextInput(attrs={'placeholder': 'Confirm Email'}))
password = forms.CharField(label='', widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
avatar = forms.ImageField(upload_to='profile_images')
class Meta:
model = User
fields = [
'username',
'email',
'email2',
'password'
]
但是这个出现
TypeError: __init__() got an unexpected keyword argument 'upload_to'
问题是,如果我将 ImageField 对象添加到模型中,我认为它会起作用,但我没有模型,如您所见,我正在使用 get_user_model(),是否有在模型表单中使用 upload_to 的方法,或者我如何添加到默认的 'get_user_model' ImageField 对象?
你应该制作一个额外的模型来存储头像,或者你可以制作一个custom user model。
如果你制作一个额外的模型,例如Profile
,你可以将其定义为:
# app/models.py
from django.conf import settings
from django.db import models
class Profile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
editable=False
)
avatar = models.ImageField(upload_to='profile_images/')
然后你可以做两个ModelForm
例如。事实上,对于 User
,您最好使用 UserCreationForm
[Django-doc],因为它已经实现了验证密码是否匹配的逻辑,并且它还会透明地散列密码。
因此,您可以为 Profile
定义一个 ModelForm
,并使用:
# app/forms.py
from django import forms
from app.models import Profile
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['avatar']
在视图中,您可以使用两种形式:
# app/views.py
from app.forms import ProfileForm
from django.contrib.auth.forms import UserCreationForm
def some_view(request):
if request.method == 'POST':
form = UserCreationForm(request.POST, request.FILES)
form2 = ProfileForm(request.POST, request.FILES)
if form.is_valid() and form2.is_valid():
user = form.save()
form2<b>.instance.user = user</b>
form2.save()
return redirect(<i>'name-of-some-other-view'</i>)
else:
form = UserCreationForm()
form2 = ProfileForm()
return render(request, <i>'name-of-some-template.html'</i>, {'form': form, 'form2': form2})
因此您在同一个 <form>
标签中呈现两种形式:
<form action="{% url 'some_view' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ <b>form</b> }}
{{ <b>form2</b> }}
</form>