So I have this model forms:
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'
]
But this appear
TypeError: __init__() got an unexpected keyword argument 'upload_to'
The problem is that I think it will works if I add the ImageField object to the model, but I dont have a model, As you can see I am using the get_user_model(), is there a way to use upload_to in model forms, or how can I add to the default 'get_user_model' the ImageField object?
You should make an extra model then to store the avatar, or you can make a custom user model.
If you make an extra model, for example Profile
, you can define this as:
# 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/')
Then you can make two ModelForm
s for example. In fact for the User
, you better use the UserCreationForm
[Django-doc], since this already implements logic to validate if the passwords match, and it will also transparently hash the password.
You thus can define a ModelForm
for the Profile
, and work with:
# app/forms.py
from django import forms
from app.models import Profile
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['avatar']
In the view, you then work with two forms:
# 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.instance.user = user
form2.save()
return redirect('name-of-some-other-view')
else:
form = UserCreationForm()
form2 = ProfileForm()
return render(request, 'name-of-some-template.html', {'form': form, 'form2': form2})
and you thus render both forms in the same <form>
tag:
<form action="{% url 'some_view' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
{{ form2 }}
</form>