Passing context on an html with both POST and GET options - html

I have a html page with various submit buttons:
<h3>Add Address</h3>
<form method="post">
{% csrf_token %}
...
<input type="submit" value="Add" name="_add_add">
</form>
<h3> Update values </h3>
<form method="post">
{% csrf_token %}
...
<input type="submit" value="Add" name="_update">
</form>
<h3>Address</h3>
<form method="get">
...display...
My view.py is:
def property(request):
if request.method == 'POST':
if '_update' in request.POST:
...update values...
elif '_add_add' in request.POST:
...add addres....
Context = {"name_for_template":"value"}
else:
... graph default values...
Context = {"name_for_template":"value"}
return render(request, 'address.html', context)
When there isn't a POST and simply a GET (like being redirected to the page), I get an CSRF error in the context (and it asked me to use request_context). Is it possible (and how) to automatically send a default context for the GET, and send a different context for POST without incurring the CSRF error?

you can try this edit code
def property(request):
context = {}
if request.method == 'POST':
if '_update' in request.POST:
...update values...
elif '_add_add' in request.POST:
...add addres....
context["name_for_template"]= "value"
else:
... graph default values...
context["name_for_template"]= "value"
return render(request, 'address.html', context)
if it doesn't work, share your code

Related

reset form method value to default when page refreshes

login.html
<form action="/login" method="post" name="login" id="login">
<input autocomplete="off" id="username" name="username" value="{{ hold }}" type="text">
<input id="password" name="password" type="password">
<button type="submit">Log In</button>
</form>
In above I have press submit button, while username is empty.
Then form submit with the post method and return render_template("login.html", xvalue=2) have executed.
After that I have refresh the login web page and I expect the request.method been assumed as default (get) and return render_template("login.html", xvalue=4) get executed.
But xvalue=2 passed, while the form method value is remained post.
#app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
if not request.form.get("username"):
return render_template("login.html", xvalue=2)
else:
return render_template("login.html", xvalue=3)
else:
return render_template("login.html", xvalue=4)
How can form method variable gets default get value, in case of page refreshed?
This is what i tried and it seemd to work
#app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
if not request.form.get("username"):
return render_template("login.html", xvalue=2)
else:
return render_template("login.html", xvalue=3)
elif request.method == "GET":
return render_template("login.html", xvalue=3)
hope this helps

After i write form media in html template, i cannot upload everything

I want to add ckeditor5 in my template ,so i add {{form.media}} to my template.
After writing {{form.media}} code , i cannot upload everything.
It seems input tag not fuction it.
Please help me to figure out what happened!!
THX~~
my code is down below:
view
def post(request):
Form = PostForm()
if request.method == 'POST':
Form = PostForm(request.POST)
Form.save()
return render(request, "Upload_done.html")
else:
return render(request, "upload.html", {'Form': Form})
html
<form action="" method="POST" enctype="multipart/form-data">{% csrf_token %}
{{ Form.media }}
{{ Form.as_p }}
<input type="submit" value="Upload">
form
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'content']
model
class Post(models.Model):
title = models.CharField(max_length=100)
content = CKEditor5Field(config_name='extends')
created_at = models.DateTimeField(auto_now_add=True)
What is happening is that content is rendered as a textarea and CKEditor hides it by adding some inline CSS to it's element. Most WYSIWYG editors don't directly change the contents of the form field with the users input and rather change the content when the form is submitted. This becomes a problem here because the browser tries to validate the form before submission but the field is empty (the JavaScript to fill it hasn't run yet) and it also has the required attribute.
Due to this your form is not submitted, adding onto the problem the error popup the browser should be displaying is also not displayed due to the CSS that is hiding the element. The solution to all this is to indicate to the browser to simply not validate the form by using the novalidate attribute on the form tag:
<form action="" method="POST" enctype="multipart/form-data" novalidate>
{{ Form.media }}
{{ Form.as_p }}
<input type="submit" value="Upload">

how to get post data in django from iterating over different id

I am creating a app which is quetion and 4 options.Each time it gives different 5 quetions.using a id in html page i am creating a radio button for each choice.Now how can save this value by post method in database.
views.py
def result(request,id) :
if request.method=='POST':
selected_choice = request.POST['choice.id']
return redirect('list_view.html')
else:
return render (request,'create_view.html')
urls.py
path('result/<id>',views.result,name='result')
html page
<div>
{% for element in q %}
<h2>{{element.id}} .{{element.question}}</h2>
<form action="{% url 'app1:result' element.id %}" method="POST">
{% csrf_token %}
{% for choice in c %}
{% if element.id == choice.id %}
<input name="{{choice.id}}" type="radio" >{{choice.choice1}}<br>
<input name="{{choice.id}}" type="radio" >{{choice.choice2}}<br>
<input name="{{choice.id}}" type="radio" >{{choice.choice3}}<br>
<input name="{{choice.id}}" type="radio" >{{choice.choice4}}<br>
{% endif %}
{% endfor %}<br>
{% endfor %}
<input type="submit" value="submit">
</form>
</div>
models.py
class Question(models.Model):
question=models.CharField(max_length=100)
def __str__(self):
return self.question
class Choice(models.Model):
choice1=models.CharField(max_length=50)
choice2=models.CharField(max_length=50)
choice3 = models.CharField(max_length=50)
choice4 = models.CharField(max_length=50)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
I would for sure try to go for Django forms for this. It is much easier. Check the answer from this question where it is detailed how to configure a radio button using Django forms.
You would like to change the input name of your choices from {{choice.id}} to choiceid-{{choice-id}}, it makes implementation easier.
For each input radio choice field, add a value attribute, for ex:
<input name="{{choice.id}}" type="radio" value="choice1">{{choice.choice1}}<br>
Create a ChoiceAnswer model with choice as foreign key.
for key in request.POST:
if key.startswith('choiceid-'):
# You can access user by request.user .
# Extract the choice here so that you can reference it in ChoiceAnswer instance.
choice = get_object_or_404(Choice, id=key.split('-')
if request.POST[key] == 'choice1':
# save data in your answer model here that choice1 has been selected.
elif request.POST[key] == 'choice2':
# save data in your answer model here that choice2 has been selected.

django inserting data into db using html template

I'm new in django. I'm trying to connect already made an html file to django backend without rebuilding whole file.
Already created forms and views in python but have no idea what to put into html file.
view class:
class signup(View):
template = loader.get_template('signup.html')
form_class = UserRegistrationForm
def get(self, request):
form = self.form_class(None)
return render(request, 'signup.html', {'form': form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
current_user = form.save(commit=False)
email = form.cleaned_data['email']
password = form.cleaned_data['password']
current_user.set_password(password)
current_user.save()
userToAuthenticate = authenticate(email=email, password=password)
if userToAuthenticate is not None:
if userToAuthenticate.is_active:
login(request, userToAuthenticate)
return redirect('siteViews:index')
return render(request, 'signup.html', {'form': form})
form code:
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ['email', 'password']
and html code:
<div id="registersquare">
<div id="panel">
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<label for="email">Email adress:</label>
<input type="email" id="username" name="email}">
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<label for="password">Repeat password:</label>
<input type="password" id="password" name="repeatedpassword">
<label class="control-label col-sm-2" for="password">{{ field.label_tag }}</label>
<div id="lower">
<input type="checkbox"><label class="check" for="checkbox"><a style="color: #999999;" href="#">I Accept Website Terms And Conditions.</a></label>
<input type="submit" value="Sign up">
</div>
</form>
</div>
</div>
anyone can explain how to do it?
cheers
You hav already created a Form, which is not Django's form, so you dont actually have to write anything in forms.py, as the purpose of it is to create an form based on the model structure and perform validations according to the fields defined.
Now you have to fetch data from form and perform the validation and checks by yourself in views. So the post would be
def post(self, request):
email = request.POST.get('email') # get value in name="email" field
password = request.POST.get('password')
repeatedpassword = request.POST.get('repeatedpassword')
if password == repeatedpassword: # manual validation to check if both string are same
# Other Validations code here and
# Register or Login etc functions here
return render(request, 'signup.html', {'form': form})
You need to delete the labels and inputs from your html file and add this tag after the {% csrf_token %}, {{form.as_p}}, that's a start. You are also using an older version of Django, the way I can tell is because when you defined your ModelForm you wrote forms.ModelForm when it has been changed to just ModelForm, to upgrade write
pip install -U Django
You essentially created two forms, one with just html and one with Django only you did not apply your ModelForm to your html file instead you just made a html form instead of a html rendered Django ModelForm.

Email sending in django code is not working

Email sending in django code is not working,
it display error "[Errno 10061] No connection could be made because the target machine actively refused it"
these are my VIEWS.PY
def send_email(request):
username = request.POST.get('username', '')
from_email = request.POST.get('from_email', '')
message = request.POST.get('message', '')
if username and message and from_email:
try:
send_mail(username, from_email, message, ['canonizadocharm#ymail.com'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return HttpResponseRedirect('/contact/thanks/')
else:
# In reality we'd use a form class
# to get proper validation errors.
return HttpResponse('Make sure all fields are entered and valid.')
these are my contact.html
<FORM METHOD="POST" ACTION="/send_email/" >
{% csrf_token %}
Name: <INPUT TYPE="text" NAME="username"><BR>
Email: <INPUT TYPE="text" NAME="from_email"><BR>
Message: <BR>
<TEXTAREA NAME="message" ROWS="10" WRAP="hard">
</TEXTAREA>
<INPUT NAME="redirect" TYPE="hidden">
<INPUT NAME="NEXT_URL" TYPE="hidden">
<BR>
<INPUT TYPE="submit" VALUE="Send">
<INPUT TYPE="reset" VALUE="Clear">
</FORM>
these are my URLS.PY
url(r'^send_email/', views.send_email),
url(r'^contact/', views.contact),
url(r'^thanks/', views.thanks),
and my SETTINGS.PY
EMAIL_HOST = 'localhost'
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_PORT = 25
EMAIL_USE_TLS = True
Your action value of form must direct to view's url, mailto:canonizadocharm#ymail.com is not a valid path on your server.
UPDATED:
For example, add a new rule to urls.py like,
url(r'^mail/', views.send_mail),
Then change action value to mail.
Have your action value point to a URL, which in turn points to one of your views. For instance, your urls.py can do this.
url(r'^email/', 'project.views.send_email')
This will route your contact form to your send_mail view.
Your form in the templates has no csrf that's why you get an error of "CSRF verification failed".
<FORM METHOD=POST ACTION="/send_email/" ENCTYPE="text/plain">{% csrf_token %}
...........
</FORM>
If you want to know what is csrf just go to this link:
https://docs.djangoproject.com/en/dev/ref/contrib/csrf/
Create email setting in your settings.py, like this for example:
settings.py
# Sending mail
EMAIL_USE_TLS = True
EMAIL_HOST='smtp.gmail.com'
EMAIL_PORT=587
EMAIL_HOST_USER='your gmail account'
EMAIL_HOST_PASSWORD='your gmail password'
views.py
from django.core.mail import send_mail
def send_email(request):
if request.method == 'POST':
username = request.POST.get('username')
message = request.POST.get('message')
from_email = request.POST.get('from_email')
send_mail(username, message, from_email, ['canonizadocharm#ymail.com',])
return HttpResponseRedirect('/contact/thanks/')
else:
return HttpResponse('Make sure all fields are entered and valid.')