When I click the button, nothing happens - python

I tried to add new passenger and when I click on the button submit nothing happens, no error is thrown. I'm new in Django
urlpatterns = [
path("", views.index, name="index"),
path("<int:flight_id>", views.flight, name="flight"),
path("<int:flight_id>/book", views.book, name="book")
def flight(request, flight_id):
flight = Flight.objects.get(pk=flight_id)
return render(request, "flights/flight.html", {
"flight": flight,
"passengers": flight.passengers.all(),
"non_passengers": Passenger.objects.exclude(flights=flight).all()
def book(request, flight_id):
if request.method == "POST":
flight = Flight.objects.get(pk=flight_id)
passenger = Passenger.objects.get(pk=int(request.POST["passenger"]))
passenger.flights.add(flight)
return HttpResponseRedirect(reverse("flight", args=(flight.id)))
})
<form action="{% url 'book' flight.id %}" method="post">
{% csrf_token %}
<select name="passenger">
{% for passenger in non_passengers %}
<option value="{{ passenger.id }}">{{ passenger }}</option>
{% endfor %}
</select>
<input type="submit"
</form>

Related

Getting NoReverseMatch even though url patterns are correct?

I've been learning Django for like a month so apologies if I'm doing something stupid, but, I'm getting a NoReverseMatch Reverse for 'profile' with arguments '('',)' not found. 1 pattern(s) tried: ['profile/(?P<use>[^/]+)$'] error when trying to render a "profile" page under the url '/profile/[a user's name]', and I'm pretty sure all my paths/patterns are correct?? Here's my code, could someone help me with this? All my other url patterns work fine. This path also worked fine before, I just renamed the "user" variable into "use" and this happened.
urls.py:
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
path("profile/<str:use>", views.profile, name="profile"),
path("following", views.following, name="following"),
#api
path('', include(router.urls)),
]
views.py:
def profile(request, use):
currentuser = str(request.user)
followers = []
following = []
for follow in Follow.objects.filter(following=use):
followers.append(follow.person)
for item in Follow.objects.filter(person=use):
following.append(item.following)
follower_count = len(followers)
following_count = len(following)
try:
Follow.objects.get(person=currentuser, following=use)
followed = True
except:
followed = False
post_list = Post.objects.filter(user=use)
dates = []
for post in post_list:
dates.append(post.timestamp)
dates.sort(key = lambda date: datetime.strptime(date, '%B %d, %Y, %I:%M %p'), reverse=True)
formattedlist = []
for date in dates:
postobject = Post.objects.get(timestamp=date)
formattedlist.append(postobject)
paginatorlist = Paginator(formattedlist, 10)
now_page_content = paginatorlist.page(1)
nowpage = 1
if request.method == "POST":
# Update the database
followbutton = request.POST.get("button")
button = request.POST.get("nav-button")
pagenum = request.POST.get("pg")
if followbutton:
if followbutton == "Follow":
followid = Follow.objects.all().count() + 1
person = currentuser
following = use
newfollow = Follow(followid, person, following)
newfollow.save()
return HttpResponseRedirect(f"/profile/{use}")
else:
deletefollow = Follow.objects.get(person=currentuser, following=use)
deletefollow.delete()
return HttpResponseRedirect(f"/profile/{use}")
else:
currentpage = paginatorlist.page(pagenum)
if button == 'Previous':
if pagenum == '1':
return render(request, "network/profile.html", {
"formattedlist": now_page_content, "currentnumber": nowpage, "message":'No previous page', "use": use, "currentuser": currentuser, "follower_count": follower_count, "following_count": following_count, "followed": followed,
})
else:
nowpage = int(pagenum)-1
now_page_content = paginatorlist.page(nowpage)
return render(request, "network/profile.html", {
"formattedlist": now_page_content, "currentnumber": nowpage, "use": use, "currentuser": currentuser, "follower_count": follower_count, "following_count": following_count, "followed": followed,
})
else:
if currentpage.has_next() == False:
return render(request, "network/profile.html", {
"formattedlist": currentpage, "currentnumber": pagenum, "message":'No next page', "use": use, "currentuser": currentuser, "follower_count": follower_count, "following_count": following_count, "list": formattedlist, "followed": followed,
})
else:
nowpage = int(pagenum)+1
now_page_content = paginatorlist.page(nowpage)
return render(request, "network/profile.html", {
"formattedlist": now_page_content, "currentnumber": nowpage, "use": use, "currentuser": currentuser, "follower_count": follower_count, "following_count": following_count, "followed": followed,
})
return render(request, "network/profile.html", {
"use": use, "currentuser": currentuser, "follower_count": follower_count, "following_count": following_count, "followed": followed, "formattedlist": now_page_content, "currentnumber": nowpage,
})
network/profile.html
{% extends "network/layout.html" %}
{% block body %}
<script src="http://127.0.0.1:8000/static/network/network.js"></script>
<div>
<h2 class="profiletext">{{use}}'s profile page</h2>
{{use}}
{% if message %}
<h6 style="color: red; margin-left: 10px">{{message}}</h6>
{% endif %}
<h5 class="profiletext">Follows: {{follower_count}} // Following: {{following_count}}</h5>
{% if use != currentuser %}
<form method="POST" class="profiletext" action="{% url 'profile' use %}">
{% csrf_token %}
{% if followed == False %}
<input type="submit" value="Follow" name="button">
{% else %}
<input type="submit" value="Unfollow" name="button">
{% endif %}
</form>
{% endif %}
</div>
{% for post in formattedlist %}
<div class="post">
<h5>{{post.use}}</h5>
<h6 style="font-weight: 60" class="edit"><a>Edit</a></h6>
<h4 class="content" style="font-size: 16px;">{{post.content}}</h4>
<h6 style="color: #d3d3d3; font-weight: 50">{{post.timestamp}}</h6>
<h1 class="hidden">{{post.id}}</h1>
{% if user.is_authenticated %}
<img src="https://cdn.shopify.com/s/files/1/0649/0603/products/bigo-0002-GH-8-bit-heart_grande.jpeg?v=1410449344">
<h2 class="likes">TODO</h2>
{% endif %}
</div>
{% endfor %}
<div>
<form class="pagination" method="POST" action="{% url 'profile' use %}">
{% csrf_token %}
<input type="submit" value="Previous" class="page-link" name="nav-button">
<input type="submit" value="Next" class="page-link" name="nav-button" >
<input type="text" value={{currentnumber}} class="pagenumber" name="pg">
</form>
</div>
{% endblock %}
I assume you have not changed user foreignkey from Post model. So, I guess your error is from this line:
<h5>{{post.use}}</h5>
So, it should be like:
<h5>{{ post.user }}</h5>

Post JS variables to Django view and display as context variables in separate template

I'm trying to achieve three things:
collect some user input using standard HTML forms in one template (questions.html below);
post that input to my views.py; and finally
display that input as context variables in a separate template (results.html below).
Once I get this to work, I'll do some processing of the input in the views.py before passing some output on as a context variable - but first I need to figure out the basic principle of moving from user input in one template --> views.py --> context variables in another template.
Also, I'm deliberately doing this without touching any database, since I don't want to save any user data.
Here's what I have for my questions.html, collecting age and level of education:
<script type="text/javascript">
$(document).ready(function(){
$('#submit_answers').submit(function (event) {
var user_age = document.getElementById("age-choice").value;
var user_education = document.getElementById("education-choice").value;
$.ajax({
type:"POST",
url:"{% url 'results' %}",
data : {
'age': user_age,
'education': user_education,
'csrfmiddlewaretoken':$("input[name=csrfmiddlewaretoken]").val()
},
})
}
)});
</script>
<p>Please answer the following questions:</p>
<p>What is your age?</p>
<form action="" method="GET" id="age-dropdown">
{% csrf_token %}
<select class="browser-default custom-select" id="age-choice">
<option value="18-30">18-30</option>
<option value="30-40">30-40</option>
<option value="40-50">40-50</option>
<option value="50-65">50-65</option>
<option value="65-100">Over 65</option>
</select>
</form>
<p>What is your highest level of education?</p>
<form action="" method="GET" id="education-dropdown">
{% csrf_token %}
<select class="browser-default custom-select" id="education-choice">
<option value="None">None</option>
<option value="GCSE">GCSE</option>
<option value="A-level">A-level</option>
<option value="University">University</option>
<option value="Postgraduate">Postgraduate</option>
</select>
</form>
<form id="submit_answers" method="post">
{% csrf_token %}
<input type="submit" name="submit_answers" class="btn btn-primary btn-sm pull-right" value="Submit" />
</form>
Here's my urls.py:
urlpatterns = [
path('', HomePageView.as_view(), name='home'),
path('questions/', QuestionsView.as_view(), name='questions'),
path('results/', ResultsView.as_view(), name='results'),
]
And here's my views.py:
class QuestionsView(TemplateView):
template_name = 'questions.html'
class ResultsView(TemplateView):
template_name = 'results.html'
def answers(request):
if request.method == 'POST':
context = {}
context["age"] = request.POST['age']
context["education"] = request.POST['education']
return context
And results.html:
<p>Results:</p>
Age: {{ age }} <br />
Education: {{ education }}
With the above, I get this in the Terminal:
Method Not Allowed (POST): /results/
Method Not Allowed: /results/
[03/Dec/2019 15:43:22] "POST /results/ HTTP/1.1" 405 0
Method Not Allowed (POST): /questions/
Method Not Allowed: /questions/
[03/Dec/2019 15:43:22] "POST /questions/ HTTP/1.1" 405 0
What am I doing wrong?
Thanks to #DanielRoseman and #Matthias for their suggestions. I followed Daniel's suggestion to switch to forms, and Matthias's suggestion to drop the JS, as follows:
First the form, forms.py:
EDUCATION_CHOICES= [
('none', 'None'),
('gcse', 'GCSE'),
('alevel', 'A-level'),
('university', 'University'),
]
class UserInputForm(forms.Form):
age = forms.IntegerField(label='Enter your age')
education = forms.CharField(label='What is your highest level of education?', widget=forms.Select(choices=EDUCATION_CHOICES))
Then the form template, userinputform.html:
<form action="/results/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
And the views.py where the results template now has a post method that also returns the context:
class HomePageView(TemplateView):
template_name = 'home.html'
class ResultsView(TemplateView):
template_name = 'results.html'
def post(self, request):
context = {}
context["age"] = request.POST['age']
context["education"] = request.POST['education']
return render(request, 'results.html', context)
def userinputform(request):
form = UserInputForm()
return render(request, 'userinputform.html', {'form':form});
And finally, results.html:
<p>Results:</p>
Age: {{ age }} <br />
Education: {{ education }}

Restrict each user to only vote once (Polls, django, python)

I found an similar question here, but unlike there and unlike in django official tutorial , I don't have a separate Choice class. How can I restrict every user to vote just one? What should I change in my code?
my models.py:
from django.contrib.auth.models import User
class Law(models.Model):
#some code here
yes_votes = models.IntegerField(default=0)
no_votes = models.IntegerField(default=0)
class Voter(models.Model):
user = models.ForeignKey(User)
law = models.ForeignKey(Law)
my views.py:
class LawDetailView(generic.DetailView):
model = Law
template_name = 'law_detail.html'
def get_queryset(self):
"""
Excludes any petitions that aren't published yet.
"""
return Law.objects.filter(pub_date__lte=timezone.now())
class LawResultsView(generic.DetailView):
model = Law
template_name = 'law_results.html'
def law_yes_vote(request, law_id):
if Voter.objects.filter(law_id=law_id, user_id=request.user.id).exists():
return render(request, 'law_detail.html', {
'law': p,
'error_message': "Sorry, but you have already voted."
})
else:
p = get_object_or_404(Law, pk=law_id)
p.yes_votes += 1
p.save()
return HttpResponseRedirect(reverse('laws:law_results', args=(p.id,)))
def law_no_vote(request, law_id):
if Voter.objects.filter(law_id=law_id, user_id=request.user.id).exists():
return render(request, 'law_detail.html', {
'law': p,
'error_message': "Sorry, but you have already voted."
})
else:
p = get_object_or_404(Law, pk=law_id)
p.no_votes += 1
p.save()
return HttpResponseRedirect(reverse('laws:law_results', args=(p.id,)))
my law_detail.html:
{% if request.user.is_authenticated %}
{% if error_message %}
<h1 >{{ error_message }}</h1>
{% else %}
<div class="row" id="row-voting">
<form action="{% url 'laws:law_yes_vote' law.id %}" method="post">
{% csrf_token %}
<button class="btn btn-success" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" >
<label >YES</label>
</form>
<form action="{% url 'laws:law_no_vote' law.id %}" method="post">
{% csrf_token %}
<button class="btn btn-danger" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" >
<label >NO</label>
</form>
</div>
{% endif %}
{% else %}
<h1>Please, register</h1>
{% endif %}
It looks like you have forgotten to create the voter instance after the user has voted.
def law_yes_vote(request, law_id):
if Voter.objects.filter(law_id=law_id, user_id=request.user.id).exists():
return render(request, 'law_detail.html', {
'law': p,
'error_message': "Sorry, but you have already voted."
})
else:
p = get_object_or_404(Law, pk=law_id)
p.yes_votes += 1
p.save()
Voter.objects.create(law_id=law_id, user_id=request.user.id)
return HttpResponseRedirect(reverse('laws:law_results', args=(p.id,)))
You'll need to update law_no_vote in the same way.

NoReverseMatch at /why is this occuring?

I had this error before but I couldn't fix it, so I moved back to previous git state. Now I have to fix this, why does this error keep happening? And what does this even mean? It's occuring from index.html {% url vote_for_post %} Here's my code, thanks in advance.
views.py
def index(request):
categories = Category.objects.order_by('likes')
latest_posts = list(Post.objects.order_by('pub_date')[:50])
hot_posts = sorted(latest_posts, key=lambda x: x.hot(), reverse=True)
controversial_topics = sorted(latest_posts, key=lambda x: x.controversy(), reverse=True)
context_dict = {
'latest_posts': latest_posts,
'categories': categories,
'hot_posts': hot_posts,
'controversial_topics':controversial_topics
}
return render(request, 'main/index.html', context_dict)
def vote_for_post(request, category_name, post_id):
category = get_object_or_404(Category, name=category_name)
post = get_object_or_404(Post, id=post_id, category=category)
if request.POST['type'] == 'upvote':
post.upvotes += 1
if request.POST['type'] == 'downvote':
post.downvotes += 1
post.save()
if request.POST['referer'] == 'index':
return HttpResponseRedirect(reverse('main:index'))
if request.POST['referer'] == 'category':
return HttpResponseRedirect(reverse('main:category', args=(category.name,)))
urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
#url(r'^add_post/', views.add_post, name='add_post'),
url(r'^add_post/$', PostCreateView.as_view(), name='post-add'),
url(r'^vote/$', views.vote_for_post, name='vote_for_post'),
url(r'^(?P<slug>[\w|\-]+)/edit/$', PostUpdateView.as_view(), name='post-edit'),
url(r'^(?P<slug>[\w|\-]+)/delete/$', PostDeleteView.as_view(), name='post-delete'),
url(r'^add_category/', views.add_category, name='add_category'),
url(r'^(?P<slug>[\w|\-]+)/$', views.post, name='post'),
url(r'^category/(?P<category_name_slug>[\w\-]+)/$', views.category, name='category'),
]
index.html
<div class="row placeholders">
<div class="col-sm-8">
<div class="row">
{% if hot_posts %}
{% for vote in hot_posts %}
<article>
<div class="vote">
<form method="post" style="display: inline"
action="{% url vote_for_post %}">
<input type="hidden" value="upvote" name="type">
<input type="hidden" value="index_page" name="referer">
<button type="submit">+</button>
{% csrf_token %}
</form>
<form method="post" style="display: inline"
action="{% url 'main:vote' vote.category.name vote.id %}">
<input type="hidden" value="downvote" name="type">
<input type="hidden" value="index_page" name="referer">
<button type="submit">-</button>
{% csrf_token %}
</form>
</div>
</article>
<hr>
{% endfor %}
{% else %}
<p>No topics are available.</p>
{% endif %}
</div>
</div>
</div>
As I see, "add_post", "vote" and "add_category" are ambiguous with your "slug" due to regex match.
url(r'^(?P<slug>[\w|\-]+)/$', views.post, name='post'),
url(r'^vote/$', views.vote_for_post, name='vote_for_post'),
url(r'^add_post/$', PostCreateView.as_view(), name='post-add'),
url(r'^add_category/', views.add_category, name='add_category'),
Try to give a better identifier for your urls.
e.g.
url(r'^(?P<slug>[\w|\-]+)/$', views.post, name='post'),
url(r'^vote/post/$', views.vote_for_post, name='vote_for_post'),
url(r'^add/post/$', PostCreateView.as_view(), name='post-add'),
url(r'^add/category/$', views.add_category, name='add_category'),
Let me know if this helped.
From the Django documentation: https://docs.djangoproject.com/en/1.9/ref/templates/builtins/#url
{% url 'some-url-name' v1 v2 %}
In your code you should add ' ' to the name in the url template tag.
<form method="post" style="display: inline" action="{% url vote_for_post %}">
should be:
<form method="post" style="display: inline" action="{% url 'vote_for_post' %}">
Concerning the NoReverseMatch at / u'main' is not a registered namespace.
Remove the 'main:' in your (reverse('main:index')) and reverse('category', args=(category.name,)) in your views.py
if request.POST['referer'] == 'index':
return HttpResponseRedirect(reverse('index'))
if request.POST['referer'] == 'category':
return HttpResponseRedirect(reverse('category', args=(category.name,)))

NoReverseMatch Error in django while creating shopping cart app

Getting error NoReverseMatch
Reverse for 'add_to_cart' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['cart/(?P<slug>[\\w-]+)/']
urls.py
url(r'^cart/(?P<slug>[\w-]+)/', views.add_to_cart, name='add_to_cart'),
views.py
from django.core.urlresolvers import reverse
def add_to_cart(request, slug):
request.session.set_expiry(120000)
try:
the_id = request.session['cart_id']
except:
new_cart = Cart()
new_cart.save()
request.session['cart_id'] = new_cart.id
the_id = new_cart.id
cart = Cart.objects.get(id=the_id)
try:
product = Product.objects.get(slug=slug)
except Product.DoesNotExist:
pass
except:
pass
product_var = [] #product variation
if request.method == "POST":
qty = request.POST['qty']
for item in request.POST:
key = item
val = request.POST[key]
try:
v = Variation.objects.get(product=product, category__iexact=key, title__iexact=val)
product_var.append(v)
except:
pass
cart_item = CartItem.objects.create(cart=cart, product=product)
if len(product_var) > 0:
cart_item.variations.add(*product_var)
cart_item.quantity = qty
cart_item.save()
# success message
return HttpResponseRedirect(reverse("cart"))
#error message
return HttpResponseRedirect(reverse("cart"))
prod.html
<form class='form' method='POST' action='{% url "add_to_cart" product.slug %}'> {% csrf_token %}
<input class='btn btn-default btn-block' type='submit' value='Add to cart'/>
<input class="form-control" name='qty' type='number' value='1'/>
{% if product.variation_set.all %}
{% if product.variation_set.sizes %}
<select class='form-control' name='size'>
{% for item in product.variation_set.sizes %}
<option value='{{ item.title|lower }}'>{{ item.title|capfirst }}</option>
{% endfor %}
</select>
{% endif %}
{% if product.variation_set.colors %}
<select class='form-control' name='color'>
{% for item in product.variation_set.colors %}
<option value='{{ item.title|lower }}'>{{ item.title|capfirst }}</option>
{% endfor %}
</select>
{% endif %}
{% endif %}
</form>
I think i am missing something. Even if I mention other url name it displays the same error with that url pattern. Do i have to import something which can resolve it.
You haven't shown the view responsible for rendering prod.html in the first place. But it is clear from the error that the object you are passing as product to that template has an empty string for its slug attribute.
From what I am seeing you are not providing, a required argument which is the slug, and 'cart' is supposed to be a string. https://docs.djangoproject.com/en/1.8/ref/urlresolvers/
url = reverse('cart', args=(slug,))
return HttpResponseRedirect(url)

Categories