Hello i need your help i need to disable this button send when the required field are empty. I am a beginner using django and i don't know how to resolve it. Please i need your help .. i lost my time trying to find a solution.
Views.py:
def contact(request):
form = FeedbackForm(request.POST or None)
if form.is_valid():
recaptcha_response = request.POST.get('g-recaptcha-response')
url = 'https://www.google.com/recaptcha/api/siteverify'
values = {
'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
'response': recaptcha_response
}
data = urllib.urlencode(values).encode()
req = urllib2.Request(url, data=data)
response = urllib2.urlopen(req)
result = json.loads(response.read().decode())
''' End reCAPTCHA validation '''
if result['success']:
form.save()
message = u'You have feedback\nName: %s\nEmail: %s\nPhone: %s\nCountry: %s\nFeedback:\n%s' % (
form.cleaned_data['name'],
form.cleaned_data['email'],
form.cleaned_data['phone'],
form.cleaned_data['country'],
form.cleaned_data['feedback'])
try:
send_mail('NEW FEEDBACK', message, '', settings.DEFAULT_FROM_EMAIL) # to admin
send_mail('THANK YOU for contacting us', 'We will be back to you promptly.', '', [form.cleaned_data['email'],]) # to user
messages.info(request, 'SUCCESS! Your message has been sent!')
form = FeedbackForm()
except:
messages.info(request, 'Sorry, can\'t send feedback right now.')
else:
messages.error(request, 'Invalid reCAPTCHA. Please try again.')
return render(request, 'contact.html', {'active_page':'contact','form': form,})
Contact.html:
<html>
<div class="col-md-6">
<form role="form" class="form" method="post">
{% csrf_token %}
{% for field in form %}
<label for="{{ field.label }}">{{ field.label_tag }}
{% if field.field.required %}<span class="red">*</span>{% endif %}</label>{{ field.errors }}{{ field }}
{% endfor %}
<p><span class="redText">*</span> Indicates a required field</p>
<script src='https://www.google.com/recaptcha/api.js'></script>
<div class="g-recaptcha" data-sitekey=""></div>
<input type="submit" value="Send" class="btn btn-lg">
</form>
The best way to do this would be to use JavaScript and jQuery.
In this example, when you click your button you can make sure the form is valid before it submits.
$(".validate").on("click", function () {
if (!valid()) {
alert("You are missing required fields.");
return false;
}
else {
return confirm("This will submit the form. Are you sure?");
}
});
function valid() {
return false;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="submit" class="validate" value="Send" class="btn btn-lg">
This code adds a class to your button. The jQuery listens for the click, then makes a JavaScript function that would check if it is valid. If it is not, it displays an alert. If it is, it displays a confirm message.
There are many other ways to do this with JS though.
Related
and at page i'm not see csrdI try after receiving one form to get another
views.py
def get_name(request):
if request.method == 'POST':
user_code = generate_code(8)
subject = 'ver code'
message = user_code
phone = request.POST['phone']
form = NameForm(request.POST)
if form.is_valid():
Registration.objects.create(fio=request.POST['fio'],mail=request.POST['mail'])
send_mail(subject, message,settings.EMAIL_HOST_USER,[mail],fail_silently=False)
return JsonResponse({ 'form1': render_to_string( 'registers/endreg.html', {'form': NameForm1() } ) })
else:
form = NameForm()
return render(request, 'registers/detail.html', {'form': form})
def endreg(request):
if request.method == 'POST':
form = NameForm1(request.POST)
if form.is_valid():
code_use = form.cleaned_data.get("key")
try:
user = Registration.objects.get(code=code_use)
user.verification = True
user.save()
messages.warning(request, u'thanks.')
except:
messages.warning(request, u'error.')
else:
form = NameForm1()
return render(request, 'registers/endreg.html', {'form': form})
and ajax
$(document).ready(function()
{ $("#my_form").submit(function(event)
{ event.preventDefault();
$this = $(this);
$.ajax({
type: "POST",
data: $this.serialize(),
success: function(data)
{ console.log(data);
$this.html(data.form1);
},
error: function(data)
{ console.log(data);
}
});
});
});
I am facing a CSRF token missing or incorrect problem. Because it is not transferred to form 2. how can I transfer this token to a new form
detatil.html it's html first page
{% extends 'base.html' %}
{% load i18n %}
{% block content%}
<div class="main-form">
<form action="" method="post" autocomplete="off" id="my_form">
{% csrf_token %}
<div class="contact-form" >
<h1>{%trans 'Регистрация' %}</h1>
<div class="txtb">{{form.fio.label}} {{form.fio}}{{form.fio.help_text}}</div>
<div class="txtb"> {{form.purpose.label}}{{form.purpose}}</div>
<div class="container" id="none">{{form.tso.label}}{{form.tso}}</div>
<div class="txtb">{{form.phone.label}} {{form.phone}}{{form.phone.help_text}}{{form.phone.errors}}</div>
<div class="txtb"> {{form.number_car.label}}{{form.number_car}}</div>
<div class="txtb"> {{form.date_visit.label}}{{form.date_visit}}</div>
<div class="txtb"> {{form.captcha.label}}<br>{{form.captcha}}{{form.captcha.errors}}</div>
<input type="submit" value="{%trans 'send' %}" class="btn" id="btn">
</div>
</form>
</div>
{% endblock %}
it's html secon page endreg.html
{% load i18n %}
{% block content%}
<form action="" method="post" autocomplete="off" >
{% csrf_token %}
<div class="verification" >
<div class="ver">
{{form}}
</div>
<input type="submit" value="{%trans 'send' %}" class="btn1" >
</div>
</form>
{%endblock%}
csrf token is on two pages, but when I look at the code in the browser, it does not appear when I add 2 forms using ajax
since you are using render_to_string, you need to pass request object to render_to_string. You can acheive it by:
def get_name(request):
if request.method == 'POST':
user_code = generate_code(8)
subject = 'ver code'
message = user_code
phone = request.POST['phone']
form = NameForm(request.POST)
if form.is_valid():
Registration.objects.create(fio=request.POST['fio'],mail=request.POST['mail'])
send_mail(subject, message,settings.EMAIL_HOST_USER,[mail],fail_silently=False)
return JsonResponse({ 'form1': render_to_string('registers/endreg.html', {'form': NameForm1()}, request=request) })
else:
form = NameForm()
return render(request, 'registers/detail.html', {'form': form})
I'm using Django for an app that allows you to search and save recipes. I'm trying to have a form on a search results page that allows you to click 'save' and creates an object to the database without reloading the page. In the current setup when I click on the 'save' button for the form with id="add_form" I get redirected to a new url (add/) even though I've included preventDefault().
I thought this was due to me including the form action={%url 'add' %} however, I've tried removing the form action but that gave me a multiValueDictKeyError for raw_input = request.POST['ingredients'] so I thought it was calling the incorrect view function views.recipes instead of views.add. I've read some other ajax guides that explicitly state a form action so I thought that would help with the incorrect view function being called.
views.py
def recipes(request):
if request.method == 'POST':
# check for dietary restrictions
restrictions = request.POST.getlist('restrictions')
# format input ingredients
raw_input = request.POST['ingredients']
...
return render(request, 'recipes/recipes.html', {'results': results})
else:
return render(request, 'recipes/recipes.html', {'error': 'Please search for a recipe'})
#csrf_protect
def add(request):
if request.method == 'POST':
title = request.POST['title']
image = request.POST['image']
source = request.POST['source']
user = request.user
try:
recipe = Recipe.objects.get(image=image, title=title, source=source)
except ObjectDoesNotExist:
recipe = Recipe.objects.create(image=image, title=title, source=source)
finally:
recipe.users.add(user)
recipe.save()
return JsonResponse({'success': True})
else:
return JsonResponse({'success': False})
urls.py
urlpatterns = [
path('add/', views.add, name='add'),
path('', views.recipes, name='recipes'),
]
html file
{% block content %}
...
{% if user.is_authenticated %}
<form action="{% url 'add' %}" id="add_form" method="POST">
{% csrf_token %}
<input type="hidden" id="image" name="image" value="{{ result.image }}">
<input type="hidden" id="title" name="title" value="{{ result.title }}">
<input type="hidden" id="source" name="source" value="{{ result.source }}">
<button type="submit" name="recipe" class="btn btn-sm btn-outline-secondary">Save</button>
</form>
{% endif %}
{% endblock %}
{% block javascript %}
<script type="text/javascript">
$(document).ready(function() {
$("#add_form").on('submit', function(e) {
e.preventDefault();
console.log( "form submitted");
$.ajax({
type:'POST',
async: 'false',
cache: 'false',
url:'{% url 'add' %}',
data:{
image:$('#image').val(),
title:$('#title').val(),
source:$('#source').val(),
},
success:function(){
alert("Saved Recipe")
}
})
})
})
</script>
I'm expecting any clicks to the save button to stay on the same page without a reload and to call views.add which will save/create an object to the database
Change the url to $(this).attr('action'). It will automatically get the url from the form instead of explicitly defining it again while making ajax call.
$.ajax({
type:'POST',
async: 'false',
cache: 'false',
url: $(this).attr('action'),,
data:{
image:$('#image').val(),
title:$('#title').val(),
source:$('#source').val(),
},
success:function(){
alert("Saved Recipe")
}
})
I'm creating an app in which I'd like to use my own custom login form with a captcha field. My intention is to do this without using an external library (except for requests) but I couldn't add captcha field to my custom form in forms.py, so I added it directly to login.html but for some reason when I do form.is_valid() it returns an error.
I've already seen the solutions in Django - adding google recaptcha v2 to login form and Adding a Recaptcha form to my Django login page but as I said, I'd like to do this without using an external library.
views.py
...
def login_view(request):
if request.method == 'POST':
form = CustomLoginForm(request.POST)
result = is_recaptcha_valid(request)
print(result) # prints True
if form.is_valid():
username = form.cleaned_data['username']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
# Redirect to index
messages.success(request, "Logged in.")
return HttpResponseRedirect(reverse('orders:index'))
else:
messages.error(request, "Invalid credentials.")
else:
print("error")
return render(request, 'registration/login.html', {'form': CustomLoginForm()})
else:
form = CustomLoginForm()
return render(request, 'registration/login.html', {'form': form})
forms.py
class CustomLoginForm(AuthenticationForm):
email = forms.EmailField(
error_messages={
'required': 'Please enter your email.',
'invalid': 'Enter a valid email address.'
},
help_text='Email',
)
login.html
<form class="" action="{% url 'orders:login' %}" method="post">
{% csrf_token %}
{% for field in form %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<!-- ReCAPTCHAV3 -->
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey='key-here'></div>
<button class="btn btn-success" type="submit" name="">Login</button>
<!-- <input type="hidden" name="next" value="{{ next }}"> -->
</form>
is_recaptcha_valid() function already returns True so I didn't share that. I'm a beginner in Django, so if you can please explain in two words what I've done wrong instead of just posting the answer, I'd be grateful. Thank you for your time.
The AuthenticationForm is slightly different than the others..
If your check AuthenticationForm class, AuthenticationForm 's first arguments is not data like others form:
class AuthenticationForm(forms.Form):
...
def __init__(self, request=None, *args, **kwargs):
...
Thats why you need to pass request.POST to data.
So update your code like this:
def login_view(request):
if request.method == 'POST':
form = CustomLoginForm(data=request.POST)
...
I'm coding a news website,I want the user can submit the comment of the news only after they have logged in,if not,the website will return to login.html.
Now I have made it that only the user who have logged in can submit a comment,the issue is once I log off and submit a comment the error says:
Cannot assign "<SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x10fed10b8>>": "NewsComments.user" must be a "UserProfile" instance.
Note:I have rewrote the User models and rename it UserProfile .It works very well.
Here is my news/views.py:
def newsDetailView(request, news_pk):
news = News.objects.get(id=news_pk)
title = news.title
author = news.author_name
add_time = news.add_time
content = news.content
category = news.category
tags = news.tag.annotate(news_count=Count('news'))
all_comments = NewsComments.objects.filter(news=news)
comment_form = CommentForm(request.POST or None)
if request.method == 'POST' and comment_form.is_valid():
comments = comment_form.cleaned_data.get("comment")
comment = NewsComments(user=request.user, comments=comments, news=news)
comment.save()
return render(request, "news_detail.html", {
'title': title,
'author': author,
'add_time': add_time,
'content': content,
'tags': tags,
'category': category,
'all_comments': all_comments,
'comment_form': comment_form
})
Here is my news.detail.html
<form method="POST" action="">{% csrf_token %}
<div class="form-group">
<label for="exampleFormControlTextarea1"><h5>评论 <i class="fa fa-comments"></i></h5></label>
<textarea id="js-pl-textarea" class="form-control" rows="4"
placeholder="我就想说..." name="comment"></textarea>
<div class="text-center mt-3">
<input type="submit" id='js-pl-submit' class="btn btn-danger comment-submit-button" value='Submit'>
</input>
</div>
</div>
</form>
Here is my urls.py:
path('-<int:news_pk>', newsDetailView, name="news_detail"),
You could use djangos login-required-decorator.
#login_required
def newsDetailView(request, news_pk):
...
EDIT to expand the idea from my comments.
You could have two views, one with the login_required decorator. (You could also use class-based-views (CBV) if you prefer)
def view_news_details(request, news_pk):
...
#login_required
def post_comments(request, news_pk):
...
Each view would have their own url:
url(r'^(?P<news_pk>[0-9]+)/$', views.view_news_details, name='view-details'),
url(r'^(?P<news_pk>[0-9]+)/comment/$', views.post_comments, name='comment'),
Then you can have only one template but with conditional rendering. This template will be rendered by the view views.view_news_details, but the form will send its data to the other view (note the forms action attribute).
... display the news details here ...
{% if request.user.is_authenticated %}
<form method="POST" action="{% url 'comment' news_instance.pk %}">
... here goes the content of the form ...
</form>
{% endif %}
Redirect the user to your login view before let him submit any data in your views.py :
# Codes here
if request.method == 'POST': # We separe those two "if statements", because
# We want to redirect the user to login even if the form is not valid, User can bypass your security concern
# For Django < 2.0, use it with () if request.user.is_authenticated():
if request.user.is_authenticated:
return redirect("login_url_name") # Or HttpResponseRedirect("login_url")
if comment_form.is_valid():
comments = comment_form.cleaned_data.get("comment")
# Rest of codes
Important
In your template, give access to the form to only authenticated users
{% if request.user.is_authenticated %}
<form method="POST" action="">{% csrf_token %}
<div class="form-group">
<label for="exampleFormControlTextarea1"><h5>评论 <i class="fa fa-comments"></i></h5></label>
<textarea id="js-pl-textarea" class="form-control" rows="4"
placeholder="我就想说..." name="comment"></textarea>
<div class="text-center mt-3">
<input type="submit" id='js-pl-submit' class="btn btn-danger comment-submit-button" value='Submit' />
</div>
</div>
</form>
{% endif %}
You can check whether the requested user is logged-in or not by user.is_authenticated() method, which returns a boolean value.
Try the following snippet,
def newsDetailView(request, news_pk):
# code
if request.method == 'POST' and comment_form.is_valid():
if not request.user.is_authenticated():
return HttpResponse("Please do login")
comments = comment_form.cleaned_data.get("comment")
comment = NewsComments(user=request.user, comments=comments, news=news)
comment.save()
return render(request, "news_detail.html", {
'title': title,
'author': author,
'add_time': add_time,
'content': content,
'tags': tags,
'category': category,
'all_comments': all_comments,
'comment_form': comment_form
})
I am trying to authenticate a user(using the simple authenticate() function) in django.
def auth(request):
if request.method == 'POST':
auth_form = AuthenticationForm(request.POST)
if auth_form.is_valid():
auth_form.save()
user = authenticate(username=request.POST['id_username'],password=request.POST['id_password'])
if user is not None:
login(request,user)
return redirect('/profile/home/')
else:
return redirect('/')
else:
return redirect('/')
def register(request):
if request.method == 'POST':
form = SimpleUserCreation(request.POST)
if form.is_valid():
form.save()
user = authenticate(username=request.POST['id_username'],password=request.POST['id_password1'])
login(request,user)
return redirect('/profile/home/')
else:
return redirect('/')
This is the template displaying the forms - Just wanted to display login and register forms in the same page(for this example)
{% extends 'base.html' %}
{% load bootstrap_toolkit %}
{% block content %}
<div class="row">
<div class="span4 offset1 login">
<form class="form-signin" action="/auth/" method="POST">
{% csrf_token %}
{{ auth_form|as_bootstrap }}
<br>
<center>
<button class="btn btn-large btn-primary" type="submit">
Sign In
</button>
</center>
</form>
</div>
<div class="span4 offset2 signup">
<form action="/register/" method="POST">
{% csrf_token %}
{{ form|as_bootstrap }}
<br>
<center>
<button class="btn btn-large btn-primary" type="submit">
Register
</button>
</center>
</form>
</div>
</div>
{% endblock %}
I am getting an error like this:
ValueError at /auth/
The view SimpleUserAuth.auth.views.auth didn't return an HttpResponse object.
Any idea where i am going wrong?? I think its the authenticating function's inability to find the correct id for the fields...maybe i am wrong. I am a Noob :|
Cheers
In your auth method, if auth_form.is_valid() returns False, you do not return a response object.
The same is the case in def register(request): . If it is a GET request, the method does not return a response object.
Hence the error(s)
I made the mistake in these lines -
1) AuthenticationForm takes argument as follows:
AuthenticationForm(data=request.POST)
2) u can't save AuthenticationForm.
auth_form = AuthenticationForm(request.POST)
if auth_form.is_valid():
auth_form.save()
Thanks for the help karthik :)