Read-only field with pre-populated data in django form - django

I have following snippets,
# models.py
class Test(models.Model):
username = models.CharField(max_length=100)
email = models.EmailField()
# forms.py
class TestForm(forms.ModelForm):
username = forms.CharField()
email = forms.EmailField()
class Meta:
model = Test
fields = ('username', 'email')
# views.py
def test(request):
email = "example#example.com"
"""
How to pass and show the 'email' in django form/template?
"""
if request.method == 'POST':
form = TestForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
form = TestForm()
return render(request, 'test.html', {"form": form})
How can I show and re-use the value of email variable (ie,example#example.com) in Django form/template as a read-only field?

try to do this way:
class TestForm(forms.ModelForm):
.....
email = forms.EmailField(initial='{{ context.email }}', disabled=True)
.....
context, passed from view, should have 'email'

Related

Populate custom field in Django form

I would like users to have the ability to update their email address. I created a profile that has fields, but the email address is in the users table. I created a form that adds a custom form field and it works for update. However, I can't find a way to pre-populate this field on a REQUEST.GET.
# forms.py
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('name', 'timezone')
class ProfileUpdateForm(ProfileForm):
email = forms.EmailField(max_length=254)
class Meta(ProfileForm.Meta):
fields = ProfileForm.Meta.fields + ('email',)
# views.py
#login_required
#require_http_methods(["GET","POST"])
def profile_update_view(request):
context = {}
# Get the logged in users profile
profile_object = Profile.objects.get(user=request.user.id)
if request.method == 'GET':
profile_form = ProfileUpdateForm(None, instance=profile_object)
context["form"] = profile_form
# how can I add User.objects.get(id=request.user.id).email to the custom field
if request.method == 'POST':
profile_form = ProfileUpdateForm(request.POST or None, instance=profile_object)
context["form"] = profile_form
if profile_form.is_valid():
try:
# email address exists
user = User.objects.get(email=profile_form.cleaned_data.get('email'))
messages.error(request, 'Failed profile update. Email address already exists.')
except:
# email address available
# get user object
user = User.objects.get(id=request.user.id)
user.email = profile_form.cleaned_data.get('email')
# update user object
user.save()
profile_form.save()
messages.success(request, 'Successful profile update.')
return render(request, "profile.html", context)
I tend to favour class-based views, and things like this are where they come into their own. The form:
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('name', 'timezone')
email = forms.EmailField(max_length=254) #add non-model form field
And a class-based view. Handle the initial value for email in get_initial(), and updating of self.request.user in form_valid():
class ProfileUpdateView( UpdateView):
model = Profile
form_class = ProfileUpdateForm
template_name = 'profile.html' # profiles/update_profile.html would be better
# other declarations ...?
def get_initial(self):
initial = super().get_initial()
initial['email'] = self.request.user.email
return initial
# #transaction.atomic might be a good idea
def form_valid(self, form):
new_email = form.cleaned_data['email']
user = self.request.user
if user.email != new_email: # don't do a pointless non-update save
user.email = new_email
user.save()
return super().form_valid( form) # will save the profile
# forms.py
def __init__(self, *args, **kwargs):
self.email = kwargs.pop("email")
super(ProfileUpdateForm, self).__init__(*args, **kwargs)
self.initial['email'] = self.email
# views.py
if request.method == 'GET':
profile_form = ProfileUpdateForm(None, instance=profile_object, email=request.user.email)
context["form"] = profile_form
if request.method == 'POST':
profile_form = ProfileUpdateForm(request.POST or None, instance=profile_object, email=request.POST.get('email'))
context["form"] = profile_form

Passing hardcoded template select field value to django model in parallel with modelform fields

I have a contact model class and its respective modelForm:
# models.py
class Contact(models.Model):
name = models.CharField(max_length=32, blank=False)
email = models.EmailField()
subject = models.CharField(max_length=32, blank=False)
message = models.TextField(max_length=256, blank=False)
def __str__(self):
return self.email
# forms.py
class ContactForm(forms.modelForm):
class Meta:
model = Contact
fields = ('name', 'email', 'message',)
I have a respective views.py and template from where I am successfully submitting and saving the form data in my Contact model.
# views.py
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
form.save()
email_subject = f'New contact {form.cleaned_data["email_address"]}: {form.cleaned_data["name"]}'
email_message = form.cleaned_data['message']
send_mail(email_subject, email_message, settings.CONTACT_EMAIL, settings.ADMIN_EMAIL)
return redirect('home')
form = ContactForm()
context = {'form': form}
return render(request, 'web_page/contact_page.html', context)
However, as my subject field is hardcoded and consists of many values from html select tag with name="subject" and few dozens of options, I want to post it together with my modelForm fileds and save respective value in my Contact table. Is this possible anyway? I just want to avoid bringing all this existing records in forms.py as a CHOICE of my subject field.
I am on learning curve so forgive me if I am asking something stupid on top of I know already should work...

how to identify and set User model foreign keys in User details database on submitting my User Registration form

As I mentioned above I want to automatically identify the User's id from the User model and set it in my User details model as foreign key on Submitting Registration form curenty I am making changes manully to testing purpose which is not a practice for standalone website
models.py
class Student_Details(models.Model):
u_id=models.ForeignKey(User,null=True,on_delete=models.SET_NULL)
field=models.CharField(max_length=400,null=True)
class Institute_Details(models.Model):
I_id=models.ForeignKey(User,null=True,on_delete=models.SET_NULL)
name=models.CharField(max_length=400,null=True)
zipcode=models.CharField(max_length=6,null=True)
def __str__(self):return str(self.name)
class Staff_Details(models.Model):
s_id=models.ForeignKey(User,null=True,on_delete=models.SET_NULL)
Institute_from=models.ForeignKey(Institute_Details,null=True,on_delete=models.SET_NULL)
def __str__(self):return str(self.s_id)
form.py
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['id','username','first_name','last_name','email', 'password1', 'password2']
class Institute_form(ModelForm):
class Meta:
model = Institute_Details
fields=['name','zipcode']
viewspy
#unauthenticated_user
def registerPage(request):
form = CreateUserForm()
form2 = Institute_form(request.POST)
if request.method == 'POST':
form = CreateUserForm(request.POST)
form2 = Institute_form(request.POST)
if form.is_valid():
if request.POST.get('user_type') == 'User':
user1 = form.save()
group1 = Group.objects.get(name='Student')
user1.groups.add(group1)
elif request.POST.get('user_type') == 'Institute':
user2 = form.save()
form2.save()
group2 = Group.objects.get(name='Institute')
user2.groups.add(group2)
return redirect('default')
context = {'form': form,'Iform':form2}
return render(request, "htmls/signup.html", context)
def logoutUser(request):
logout(request)
return redirect('default')

What is the easiest way to require the user to fill in default fields of the User model like first name and last name in Django in UserCreationForm?

I am using Django built-in authentication views and form to create a registration/login system, and I'm using the UserCreationForm to register a user but only the username is required. I only want to make other User fields required as well. What is the simplest way to do that without creating a new user model?
Here are my forms:
# Create user registration form class.
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = User
fields = UserCreationForm.Meta.fields + ('first_name', 'last_name', 'email',)
And here are my views:
def register(request):
if request.user.is_authenticated:
return HttpResponseRedirect(reverse('index'))
elif request.method == 'GET':
form = CustomUserCreationForm()
elif request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
form.save()
context = {
'user': request.user,
}
return HttpResponseRedirect(reverse('index'), context)
else:
return HttpResponseRedirect(reverse('register'))
else:
return HttpResponse("Project 3: TODO")
context = {
'form': form,
}
return render(request, 'registration/signup.html', context)
You can override the fields for first and last name on the form to make them required. Note, this won't change the fact that the database table still allows null values for those fields
class CustomUserCreationForm(UserCreationForm):
first_name = forms.CharField(required=True, max_length=150)
last_name = forms.CharField(required=True, max_length=150)
class Meta:
model = User
fields = UserCreationForm.Meta.fields + ('first_name', 'last_name', 'email',)

Django: creating form which has relationship

I've prepared a model with a relationship.
I'd like to get a form which will make it possible to create User for that form.
Could someone explain me how it can be resolved?
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True, primary_key=True)
website = models.URLField(null=True, blank=True)
accepted_rules = models.BooleanField(default=False)
accepted_rules_date = models.DateTimeField(auto_now_add=True)
class UserProfile(ModelForm):
class Meta:
model = UserProfile
#csrf_protect
def register(request):
if request.method == "POST":
form = UserProfile(request.POST or None)
if form.is_valid():
website = form.cleaned_data['website']
accepted_rules = form.cleaned_data['accepted_rules']
username = form.cleaned_data['username']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
form.save()
print "All Correct"
return TemplateResponse(request, 'base.html', {
'form':form,
}
)
Here is one way I would consider. First of all, I would name the form UserProfileForm so that it's name doesn't conflict with the model. Add extra fields to your UserProfile form for the fields required to create a new user. Create the new User instance. Use form.save(commit=False) so that you can add the newly created User instance to the UserProfile instance and save it. There may be a more elegant way.
from django import forms
class UserProfileForm(forms.ModelForm):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput())
email = forms.EmailField()
class Meta:
model = UserProfile
from django.contrib.auth.models import User
#csrf_protect
def register(request):
if request.method == "POST":
form = UserProfileForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
user = User(username=username, email=email)
user.set_password(password)
user.save()
user_profile = form.save(commit=False)
user_profile.user = user
user_profile.save()
print "All Correct"
return TemplateResponse(request, 'base.html', {'form':form})