Form not submitting to correct url in django - html

Im making a web app in django and im having a problem with a form which isnt submitting to the correct place
searcc.html
<form method='POST', action='/saveApply'">
{% csrf_token %}
<div class="JobSub">
<input value="{{user.id}}" name="usrid">
<input value="{{comp.id}}" name="compid">
<button type="submit">Submit</button>
</div>
</form>
views.py
def saveApply(request):
current_user = request.user
if request.method == 'POST': # Foreign key to User is just the username
savedApply.objects.create(
user = request.POST.get('usrid'),
company = request.POST.get('company')
)
return render('main/profile.html') # Change later
return redirect('login')
The confusing thing is, when I press on the submit button Im not even getting sent to the login view. I am getting sent to the home page. I think the problem has something to do with the fact that this html page is getting included in another.
main.html
{% include 'main/search.html' %}
{% endblock %}
Main.html is also inheriting from another file
Urls.py
path('saveApply/', views.saveApply, name="saveApply"),
path('feed/', views.feed, name='feed'),

Related

Same-site iframes not able to connect in Django

The iframe displays that it cannot connect. I've tried using the default #xframe_options_exempt decorator on the view, aswell as django-csp's #csp_exempt to no avail.
The console errors given are:
Refused to display 'http://localhost:8000/new_pull/' in a frame because it set 'X-Frame-Options' to 'deny'.
and
Failed to load resource: the server responded with a status of 404 (Not Found)
view
#csp_exempt
#login_required
def new_pull(request):
"""Create a new pull request"""
if request.method != 'POST':
# No data submitted; create a blank form
form = PullForm()
else:
# POST data submitted; process data
form = PullForm(data=request.POST)
if form.is_valid():
new_pull = form.save(commit=False)
new_pull.owner = request.user
new_pull.save()
# Display a blank or invalid form.
context = {'form': form}
return render(request, 'learning_logs/new_pull.html', context)
base.html
{% if user.is_authenticated %}
<br>
<iframe src="{% url 'learning_logs:new_pull' %}" title="Pull request Iframe"></iframe>
<iframe src="learning_logs/new_pull.html" title="Pull request Iframe"></iframe>
{% endif %}
new_pull.html
<div class="pull container text-center border-top mt-5">
<h5 class="mt-2">Pull request</h5>
<p>New pull request:</p>
<form action="{% url 'learning_logs:new_pull' %}" method='post'>
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button name="submit" class="btn btn-green pl-2 pr-2">
<i class="fas fa-plus-circle"></i>
Create pull
</button>
{% endbuttons %}
<input type="hidden" name="next"
value="{% url 'learning_logs:bug_tracker' %}" />
</form>
</div>
Try adding this to Settings.py:
X_FRAME_OPTIONS = 'SAMEORIGIN'
By default, the X-Frame-Options are set to Deny
https://docs.djangoproject.com/en/3.0/ref/clickjacking/
This may not be your problem, as there are many things that could be causing this, such as CSP. Difficult to say for sure without my information.
First good to mention the documentation of the django-csp Configuring django-csp
Try to do first what's bones225 mentioned.
Esure header X-Frame-Options "SAMEORIGIN'; Note, you can check all your current headers in Response Headers in the Web Developer Tools (chrome: Network -> Name -> click on html page -> Headers will open on right side )
You may have directive CSP_DEFAULT_SRC = ("'self'") in place and no CSP_FRAME_SRC set.
Then add CSP_FRAME_SRC = ('localhost:8000') too.

How to redirect to other page using submit button

I am writing a view that retrieve an answer from game2.html, check the answer; if the answer is correct, the view will redirect user to correct.html, if the answer is incorrect, then user will be redirected to incorrect.html.
The problem now is after clicking the submit button, user won't be redirected. But the score is updated.
After I clicked submit button the url will change from http://localhost:8000/game2/ to http://localhost:8000/game2/?ans2=4&game2Answer=Submit instead of redirect to correct.html or incorrect.html
I guess it might be the problem of my submit button that doesn't trigger the redirect function, or it is the problem of the way I write redirect function in views, as the score is actually updated if the answer is correct.
So, how can i fix it to make it able to redirect to either correct.html or incorrect.html after going into the if-else statement.
morse_logs/views.py
#login_required()
def game2(request):
"""The Game2 page"""
if request.user and not request.user.is_anonymous:
user = request.user
def verifyGame2(val1):
user_score, created = userScore.objects.get_or_create(user=user)
if val1 == 4:
# user's score declared in model increase 5points
# display correct and 5 points added to user
user_score.score += 5
user_score.save()
return redirect('morse_logs:incorrect')
else:
# user's score declared in model has no point
# display incorrect and 0 point added to user
return redirect('morse_logs:incorrect')
ans2 = request.GET.get('ans2', '')
if ans2 == '':
ans2 = 0
verifyGame2(int(ans2))
return render(request, 'morse_logs/game2.html')
game2.html
{% extends "morse_logs/base.html" %}
{% block content %}
<title>GAME 2</title>
<div>
<h1>GAME 2</h1>
<h2>2 + 2 = ?</h2>
<form action="" method="post" >
<input type="number" id="ans1" name="ans1"/><br><br>
<input type="submit" name="game1Answer"/>
</form>
</div>
{% endblock content %}
morse_logs/correct.html
{% extends "morse_logs/base.html" %}
{% block content %}
<title>Correct!</title>
<div>
<h1>Congratulations! Your answer is CORRECT!</h1>
</div>
{% endblock content %}
morse_logs/incorrect.html
{% extends "morse_logs/base.html" %}
{% block content %}
<title>Inorrect...</title>
<div>
<h1>Unfortunately! Your answer is Incorrect!</h1>
</div>
{% endblock content %}
morse_logs/urls.py
from django.urls import path, include
from morse_logs import views
app_name = 'morse_logs'
urlpatterns = [
#The path() function is passed four arguments, two required: route and view, and two optional: kwargs, and name.
# Home Page
path(r'', views.index, name='index'),
# Page that shows all topics
path(r'topics/', views.topics, name='topics'),
path(r'cipher/', views.cipher, name='cipher'),
path(r'decipher/', views.decipher, name='decipher'),
path(r'tutorialIndex/', views.tutorialIndex, name='tutorialIndex'),
path(r'gameDirectory/', views.gameDirectory, name='gameDirectory'),
path(r'game1/', views.game1, name='game1'),
path(r'game2/', views.game2, name='game2'),
path(r'correct/', views.correct, name='correct'),
path(r'incorrect/', views.incorrect, name='incorrect'),
]
You should change your
redirect('morse_logs:incorrect.html')
to
redirect('url_name')
And also remove the app_name if you are using django version >2.0
First, I changed the template form method from "GET" to "POST" and add {% csrf_token %}.
Secondly, I changed the view into 2 parts:
1st part is when user first enter game2.html(GET request), it will render game2.html to user.
2nd part is basically what I have done before, but this time I added a case that respond to user's POST request, and from there to do redirections to either correct.html or incorrect.html
game2.html
{% extends "morse_logs/base.html" %}
{% block content %}
<title>GAME 2</title>
<div>
<h1>GAME 2</h1>
<h2>2 + 2 = ?</h2>
<form method="POST">
{% csrf_token %}
<input type="number" id="ans2" name="ans2"/><br><br>
<input type="submit" name="Submit"/>
</form>
</div>
{% endblock content %}
views.py
#login_required()
def game2(request):
"""The Game2 page"""
if request.method == "GET":
return render(request, 'morse_logs/game2.html')
elif request.method == "POST":
if request.user and not request.user.is_anonymous:
user = request.user
user_score, created = userScore.objects.get_or_create(user=user)
ans2 = request.POST.get('ans2', '') #fetch the POST data from template
if ans2 == '':
ans2 = 0
ans2 = int(ans2)
if ans2 == 4:
# user's score declared in model increase 5points
# display correct and 5 points added to user
user_score.score += 5
user_score.save()
return redirect(reverse('morse_logs:correct'))
else:
# user's score declared in model has no point
# display incorrect and 0 point added to user
return redirect(reverse('morse_logs:incorrect'))

why does my link to logout not work in my Django app?

So I'm trying to do a logout link in my Django app. I've set a view that logs out the user and then redirects him to a template paginaPrincinal.html that has two buttons for login and register.
The problem is that for some reason the link href that I'm creating in my index.html doesn't appear.
my views.py
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
return redirect('index')
else:
form = AuthenticationForm()
return render(request, 'registration/login.html', {'form': form})
def logout_view(request):
logout(request)
return redirect('paginaPrincipal')
my urls.py
path('principal/', views.intro, name='pagina_principal'),
path('registro/', views.registro_usuario, name='registro_usuario'),
path('login/', views.login_view, name="login"),
path('logout/', views.logout_view, name="logout"),
path('',views.index, name ='index'),
index.html
{% block contenido %}
<div>
<ul>
{% if user.is_authenticated %}
<li>Hola, {{user.username}}</li>
<li></li>
{% endif %}
</ul>
</div>
{% endblock %}
The error that appears if I inspect the code and try to go to the Href is this:
NoReverseMatch at /myapp2/logout/
Reverse for 'paginaPrincipal' not found. 'paginaPrincipal' is not a valid view function or pattern name.
The string you pass into redirect should be a url route name. The problem is that 'paginaPrincipal' != 'pagina_principal'
def logout_view(request):
logout(request)
return redirect('pagina_principal')
That should fix it.
You are redirecting to "paginaPrincipal", but you have defined "pagina_principal". You have to change your view function
def logout_view(request):
logout(request)
return redirect('pagina_principal')
NoReverseMatch Means you have to set app_name in the urls.py like
app_name= "app_name"
and in the templates
it should work

how to pass value from html to view in django?

I have made this HTML code:
<h3>your major is {{user.userprofile.major}}</h3>
This will correctly show the major on the webpage, but I want to use this string to get something from another table in view.
How would I pass this string to view?
edit:
Here is my view.py
def dashboardView(request):
obj = BooksFile.objects.all()
query = BooksFile.objects.filter(book_major='cs)
return render(request, 'dashboard.html', {'books': obj, 'major': query})
def registerView(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
profile_form = UserProfileForm(request.POST)
if form.is_valid() and profile_form.is_valid():
user = form.save()
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
return redirect('login_url')
else:
form = UserCreationForm()
profile_form = UserProfileForm()
context = {'form': form, 'profile_form': profile_form}
return render(request, 'registration/register.html', context)
here is my template:
{% extends 'index.html' %}
{% block content %}
<h1>Welcome, {{user.username}}</h1>
<h2>Your major is {{user.userprofile.major}}</h2>
{% for book in books %}
<h3>Your book name is {{book.book_name}}</h3>
{% endfor %}
{% endblock %}
I am trying to show the book names from the booksfile table by corresponding major that user has. Right its showing the books that has "cs" attribute because I manually put "cs" in the get function in view. I am trying to send the major string from template to view, so that I can put what ever the user's major is in the get function. Or is there any other way to do it.
You need to use a form in your template and submit it to call your view. i.e.
<form action="your_view_url" method="POST">
<input type="text" name="major" value="{{user.userprofile.major}}"/>
<input type="submit"/>
</form>
an then in your view you access that with:
if request.POST:
major = request.POST.get('major')
As per documentation: https://docs.djangoproject.com/en/2.2/topics/forms/
First of all you have to get the value of model with help of queryset, and put it in the dictionary and then pass it with the template.
In views:
def get(self, request):
queryset = Model_name.objects.all()
ctx = {
'queryset': queryset,
}
return render(request, 'page_name(or template_name).html', ctx)
in template:
<form action="{%url'(your_view_name without brackets)'%}" method="POST">
{% for data in queryset%}
<span class="username">{{data.name(field of your model)}} .
</span>
<span class="email">{{data.email(field of your model)}} .
</span>
{% endfor%}
</form>

Django : HTML form action directing to view (or url?) with 2 arguments

Started learning django about a week ago and ran into a wall. Would really appreciate any enlightenment...
models.py
class data(models.Model):
course = models.CharField(max_length = 250)
def __str__(self):
return self.course
html
Converted the objects in models.course to schlist
<link rel="stylesheet" type="text/css" href="{% static '/chosen/chosen.css' %}" />
<form action={% views.process %} method="GET">
<div>
<h4 style="font-family:verdana;">First Course: </h4>
<select data-placeholder="Course" style="width:350px;" class="chosen-select" tabindex="7">
<option value=""></option>
{% for item in schlist %}
<option> {{ item }} </option>
{% endfor %}
</select>
</div>
</br>
<div>
<h4 style="font-family:verdana;">Second Course:</h4>
<select data-placeholder="Course" style="width:350px;" class="chosen-select" tabindex="7">
<option value=""></option>
{% for item in schlist %}
<option> {{ item }} </option>
{% endfor %}
</select>
</div>
</br>
<input type="submit" value="Compare!" />
</form>
urls.py (having my doubts if this works..)
urlpatterns = [
url(r'^(\d+)/(\d+)$',views.process, name = 'process'),
]
view.py
def process(request,q1 ,q2):
obj1= get_object_or_404(Schdata, course = q1)
obj2= get_object_or_404(Schdata, course = q2)
........
Was wondering if it is possible for the form action to direct the action to
(1) view.py or (2) url.py (and eventually to a view.py) with 2 arguments selected?
If so how should the form action be? {{view ?}} or {{url ?}}. Am I missing out the definition of my arguments in my HTML?
Directing to views.py:
User input is CharField, could use get_object_or_404 to get the model pk. However when defining my urls.py I would get a Noreverse error as my url arguments is the primary key.
Directing to urls.py:
Url arguments is primary key. From the way I see it, I need to magically convert my User input Charfield to a pk before passing it to urls.py
Is there a (or) function for get() in django? E.g get_object_or_404(pk = q1 or course = q1)?
Would really appreciate any advice. Been staring at this for hours.
You are trying to use the reverse resolution of urls in Django.
In your html file correct form action url to the following and method should be POST:
<form action={% url 'process' %} method="POST">
In case you are trying to pass parameters along then use this:
<form action={% url 'process' request.user.id 4 %} method="POST">
Reference:
https://docs.djangoproject.com/en/1.10/topics/http/urls/
Yes i'm late but it can help others for better understanding how Django processes the request.
Django 3.0 pattern
How Django processes the request
Basic :
First Django check the matching URL.
If URL is matched then calling the defined view to process the request. (Success)
If URL not matched/found the Django invokes error Page Not Found
In detail reading :
Official Django Documentations How Django processes a request
These are your URL patterns :
urlpatterns = [ path('profile/edit/<int:pk>/',views.editprofile, name='editprofile'),]
Third argument in urlpatterns is for if you want to change the url pattern from current to this :
urlpatterns = [ url('profile/edit/user/id/<int:pk>',views.editprofile, name = 'editprofile'),]
You don't need to redefine url pattern in all Templates where you using url name.
For Example :
This is my template profile.html where i used the url name instead of hard coded url.
<a class="item" href="{% url 'editprofile' user.id %}" >Edit profile </a>
Solution of your problem :
.html
Only use url name instead of hard coded url in your templates and pass arguments.
<form action={% process no_of_arguments %} method="POST">
views.py
Here you can process your request
def process(request,no_of_arguments):
Become good django developer
You can also use Django ModelForms for your model.
Using model forms or simple form you can do multiple things
Modular approach
Write server side validation in related form instead of doing in views.py
Readable code - Clean code