how to take data from the admin using Django forms? - django

I want when the user to select multiple users, a pop-up form will appear and he can send emails after submitting the form to the selected users
This is admin.py
class ReplyForm(forms.Form):
message = forms.CharField(widget=forms.Textarea)
#admin.register(ContactUs)
class ContactUsAdmin(admin.ModelAdmin):
actions = ['reply_by_email']
list_display = ("id", "first_name", "last_name", "email",
"phone_number", "created_at", "message")
search_fields = ("first_name", "last_name", "email", "phone_number", "message")
def reply_by_email(self, request, queryset):
if request.POST:
form = ReplyForm(request.POST)
if form.is_valid():
subject = "Custom email from admin"
message = form.cleaned_data['message']
from_email = "admin##example.com"
recipient_list = [user.email for user in queryset]
send_mail(subject, message, from_email, recipient_list)
else:
# check the form's errors
print(form.errors)
else:
form = ReplyForm(request.POST or None)
context = self.admin_site.each_context(request)
context['form'] = form
context['queryset'] = queryset
return TemplateResponse(request, "reply_by_email.html", context)
reply_by_email.short_description = "Send email to selected users"
this is reply_by_email.html:
{% load i18n %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="apply" value="Send Email">
</form>
{% endblock %}
when the admin fill the form nothing happens
Iam expecting a message from the user

Related

Django Edit Profile View not saving new email value

I am (attempting to) implement the ability for a user to edit and update their email address on their profile page. I am getting no errors when doing this end to end but the new email is not being saved to the DB.
Everything seems to be working, even the redirect to the profile page in the edit_profile function, but the save() doesn't seem to be working, the users email doesn't update and when I am redirected back to the profile page, the email is still the current value.
Thanks!
Model:
class CustomUser(AbstractUser):
email = models.EmailField(_('email address'), unique=True)
is_pro = models.BooleanField(default=False)
is_golfer = models.BooleanField(default=False)
def __str__(self):
return self.email
Form
class EditProfileForm(forms.Form):
email = forms.EmailField(
label='', widget=forms.TextInput(attrs={'class': 'form-field'}))
View
#login_required
def edit_profile(request):
if request.method == "POST":
form = EditProfileForm(request.POST)
if form.is_valid():
email = form.cleaned_data["email"]
user = CustomUser.objects.get(id=request.user.id)
user.save()
return redirect("typeA", username=user.username)
else:
form = EditProfileForm()
return render(request, "registration/edit_profile.html", {'form': form})
URLS
urlpatterns = [
path('type_a_signup/', ASignUpView.as_view(), name='a_signup'),
path('type_b_signup/', BSignUpView.as_view(), name='b_signup'),
path('login/', LoginView.as_view(), name='login'),
path('password_reset', PasswordResetView.as_view(), name='password_reset'),
path('typea/<username>/', typeA, name='typeA'),
path('typeb/<username>/', typeB, name='typeB'),
path('login_success/', login_success, name='login_success'),
path('edit_profile/', edit_profile, name='edit_profile'),
]
Template
<div class="container">
<div class="form-container">
<h2>Edit profile</h2>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div>
{{ form.email.label_tag }}
<input type="text" class="form-control {% if form.email.errors %}is-invalid{% endif %}" id="id_email"
name="email" value='{{ form.email.value|default:user.email }}'>
{% if form.email.errors %}
<div>{{ form.email.errors }}</div>
{% endif %}
</div>
<button type="submit">Submit</button>
</form>
<br>
</div>
You never set the email field of the object. You should set this with:
#login_required
def edit_profile(request):
if request.method == "POST":
form = EditProfileForm(request.POST)
if form.is_valid():
email = form.cleaned_data["email"]
user = request.user
user.email = email # 🖘 set the email field
user.save()
return redirect("typeA", username=user.username)
else:
form = EditProfileForm()
return render(request, "registration/edit_profile.html", {'form': form})
You should only redirect in case the form is successful. If it is not, Django will rerender the form with the errors.

How can I include an image in a Django contact form?

I need to have users send me an email through my website with the front and back of their ID for verification. Why is my form returning "This field is required." when everything is filled in? What did I do wrong?
views.py
def market(request):
if request.method == 'GET':
form = ContactForm()
else:
form = ContactForm(request.POST)
if form.is_valid():
from_email = form.cleaned_data['from_email']
subject = form.cleaned_data['subject']
address = form.cleaned_data['address']
id_front = form.cleaned_data['id_front']
additional_details = form.cleaned_data['additional_details']
try:
send_mail(from_email, subject, id_front, address, additional_details, ['admin#example.com'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return redirect('market_success')
return render(request, "market.html", {'form': form})
def market_success(request):
return HttpResponse('Success! We have received your request and will get back to you soon.')
forms.py
class ContactForm(forms.Form):
from_email = forms.EmailField(required=True)
subject = forms.CharField(required=True)
address = forms.CharField(required=True)
id_front = forms.ImageField(required=True)
additional_details = forms.CharField(widget=forms.Textarea, required=True)
html
{% extends 'base.html' %}
{% block title %}Market{% endblock %}
{% block content %}
<p>To request to market your property with us, please fill out the form below.</p>
<form method="post" enctype="multipart/form-data" class="post-form">
{% csrf_token %}
{{ form.as_p }}
<div class="form-actions">
<button type="submit">Send</button>
</div>
</form>
{% endblock %}

Data not filling in with Edit Profile form Django

I'm using the following line to fill in data into the form.
form = EditProfileForm(request.POST, instance=request.user)
However, no data fills into the form. I just get the empty form. Not sure what's going wrong. I have a profile html where the data from each user shows up, but the line above is not working on the edit page. The model is the default user model. Django version 2.2.3.
#views.py
def editprofile(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
if form.is_valid():
agree = form.save(commit=False)
agree.save()
args = {'form': form}
else:
form = EditProfileForm(request.POST)
args = {'form': form}
return render(request, 'profile_edit.html', {'form':form})
Here is my forms.py:
class EditProfileForm(UserChangeForm):
username = forms.CharField(label='Username', widget=forms.TextInput(attrs={'class': "form-control"}))
first_name = forms.CharField(label='First Name', widget=forms.TextInput(attrs={'class': "form-control"}))
last_name = forms.CharField(label='Last Name', widget=forms.TextInput(attrs={'class': "form-control"}))
email = forms.CharField(label= 'Email', widget=forms.EmailInput(attrs={'class': "form-control"}))
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'email', 'password']
def save(self, commit=True):
user = super(EditProfileForm, self).save(commit=False)
user.username = self.cleaned_data['username']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
template
{% block content %}
<h3> Please edit your profile here </h3>
<div class="container">
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button href="{% url 'profilepage' %}" type="submit" >Submit</button>
</form>
<br>
</div>
{% endblock %}
Added urls.py
path('profile/', views.profile, name = 'profilepage'),
path('profile/edit/', views.editprofile, name = 'editprofile')
Try adding action to your form tag in template.
Like this:
<form action= "{% url 'editprofile' %}" method="post">
'editprofile' is the url_name of your editprofile view. Also the class Meta and method def save() should be inside your class EditProfileForm() block.

django - image isn't saving, all other fields are

When I update the user profile via the view everything is saving to the db except the image. The forms are validating but image isn't being saved. I can log in the admin portal and successfully add an image to an existing instance. I assume my problem lies in my html template but I can't figure out what it is.
**Btw I've read multiple similiar post but none I believe addresses my issue.
form.py
class EditUserForm(forms.ModelForm):
template_name='/something/else'
class Meta:
model = User
fields = (
'email',
'first_name',
'last_name',
)
class EditProfileForm(forms.ModelForm):
template_name='/something/else'
class Meta:
model = UserProfile
fields = (
'description',
'city',
'website',
'phone',
'image',
)
views.py
#transaction.atomic
def edit_profile(request):
if request.method == 'POST':
form = EditUserForm(request.POST, instance=request.user)
form2 = EditProfileForm(request.POST, instance=request.user.userprofile)
if form.is_valid() and form2.is_valid():
form.save()
form2.save()
return redirect(reverse('accounts:view_profile'))
else:
form = EditUserForm(instance=request.user)
form2 = EditProfileForm(instance=request.user.userprofile)
args = {'form': form, 'form2':form2}
return render(request, 'accounts/edit_profile.html', args)
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
description = models.CharField(max_length=100, default='')
city = models.CharField(max_length=100, default='')
website = models.URLField(default='')
phone = models.IntegerField(default=0)
image = models.ImageField(upload_to='profile_image', blank=True)
def __str__(self):
return self.user.username
edit_profile.html
<div class="container">
{% if form.errors %}
<ol>
{% for field in form %}
<H3 class="title">
<p class="error"> {% if field.errors %}<li>{{ field.errors|striptags }}</li>{% endif %}</p>
</H3>
{% endfor %}
</ol>
{% endif %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
{{ form2.as_p }}
<button type="submit">Submit</button>
</form>
<br>
</div>
If you are uploading files, you must instantiate the form with request.POST and request.FILES.
form2 = EditProfileForm(request.POST, request.FILES, instance=request.user.userprofile)
See the docs on file uploads for more info.

Can't get data in edit form

I'm trying to create an edit form for existing users, I have the User model and I associated to it a profile.
The problem is that the fields of profile are empty in the rendered html, however when I created a new user I filled these fields, and when I enter to administration I find the fields are filled.
models.py
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
DEPARTMENT_CHOICES = (('MI', 'Math et info'),
('ST', 'Science et Tech'),
('SM', 'Science de la matiere'))
user = models.OneToOneField(User, on_delete=models.CASCADE)
teacher = models.BooleanField(default=False)
description = models.TextField(blank=True)
department = models.CharField(max_length=35, choices=DEPARTMENT_CHOICES, blank=True)
picture = models.ImageField(upload_to='profile-images', blank=True)
def __str__(self):
return self.user.username
views.py
def profile_view(request):
if request.method == 'POST':
user_form = EditUserForm(request.POST, instance=request.user)
ins = Profile.objects.get(pk=5)
profile_form = EditProfileForm(request.POST, request.FILES, instance=ins)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.save()
profile = profile_form.save(commit=False)
profile.user = user
if 'picture' in request.FILES:
profile.picture = request.FILES['picture']
profile.save()
return redirect(home)
else:
user_form = EditUserForm(instance=request.user)
profile_form = EditProfileForm(request.FILES, instance=request.user)
return render(request, 'account/profile.html', {'user_form': user_form,
'profile_form': profile_form})
forms.py
class EditProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('description', 'department', 'picture', )
class EditUserForm(forms.ModelForm):
class Meta:
model = User
fields = ('username', 'email', )
profile.html
{% extends 'manhal/base.html' %}
{% load staticfiles %}
{% load crispy_forms_tags %}
{% block content %}
<div class="col-md-6">
<form method="post" enctype="multipart/form-data" action="{% url 'profile' %}" class="form-horizontal">{% csrf_token %}
<fieldset>
<legend>User Profile</legend>
{{ user_form|crispy }}
{{ profile_form|crispy}}
<input type="submit" value="Save" class="btn btn-primary">
</fieldset>
</form>
</div>
{% endblock %}
First, your if/else block is checking if the request is a POST. Since the else block is not a POST, you do not want to pass any POST data into your form. This will make the form think it's bound with no data.
Also, it looks like you are passing the request.user to your ProfileForm as the instance, but the model on the ProfileForm meta class is expecting a Profile object.
Can you fix those two things and see if it works or not? If it doesn't work, please post some more code (like your templates).