All I get is a blank page when I visit localhost:9080 - python-2.7

I have been using udacity.com to learn to program but I ran into some problem with my code(python). The application is post to allow to put down the day you were born and when you push submit it's post to say "Thanks That's a totally valid day!". It's not doing it. The application just restarts again. Can some tell me why the is statement is not working and how to fix it.
import webapp2
form="""
<form>
What is your birthday?
<br>
<label>Month<input type="type" name="month"></label>
<label>Day<input type="type" name="day"></label>
<label>Year<input type="type" name="year"></label>
<div style="color: red">%(error)s</div>
<br>
<br>
<input type="submit">
</form>
"""
class MainPage(webapp2.RequestHandler):
def write_form(self, error=""):
self.response.out.write(form % {"error": error} )
def get(self):
self.write_form()
def post(self):
user_month = valid_month(self.request.get('month'))
user_day = valid_day(self.request.get('day'))
user_year = valid_year(self.request.get('year'))
if not (user_month and user_month and user_year):
self.write_form("That doesn't look valid to me, friend.")
else:
self.response.out.write("Thanks! That's a totally valid day!")
app = webapp2.WSGIApplication([('/',MainPage)], debug=True)

That fragment has a syntax error. If you're watching the terminal/console, you'll notice Python complain about the else (which is missing a trailing :). Watching the console, and understanding what it's saying, is key if you want to make progress.
With that fixed, you'll see the form. Then, when you trying posting, you'll get a "405 Method not allowed" because the post method is over-indented.

Add method="post" to your form tag just above the text "What is your birthday?". You are using post method to post data to the form but the button submit doesn't know that you are using post as the tag does not have method="post" in it.
Also check my answer on one of your other related post here. python post and get commands

Related

Django & AJAX to show DB objects upon user's input submission

I'm pretty new in the Web development world, have been using Django so far.
I've been trying to figure out how to render data back to page after clicking on a submit button, so I see I'll need to use AJAX for that purpose.
I've created a very simple app just to understand the basics of AJAX.
However, googling, I couldn't really find a basic straight-forward implementation so I kinda got lost...
What I'm trying to achieve:
I have a model called Country:
class Country(models.Model):
name = models.CharField(primary_key=True, max_length=35)
continent = models.CharField(max_length=10)
capital = models.CharField(max_length=35)
currency = models.CharField(max_length=10)
And a super simple main page that asks the user to insert some country name.
The idea is to bring to the page all the info from the DB.
So it would look like this:
Main page HTML body:
<body>
<h2><em>Please type a country name:</em></h2><br><br>
<div class="container">
<form id="get_info" method="post">
{{ form }}
{% csrf_token %}
<input id="submit_button" type="submit" name="submit" value="Get info">
</form>
</div>
</body>
views.py:
from django.shortcuts import render
from country_trivia import forms
def main_page(request):
get_info_form = forms.GetInfo()
return render(request, 'country_trivia/index.html', {'form': get_info_form})
forms.py:
from django import forms
class GetInfo(forms.Form):
country_name = forms.CharField(label="")
I've seen some examples using forms, but I'm not even sure if it's needed, as I've seen some other examples that count on 'onclick' even listeners, then "grab" the text in the search field and pass it via AJAX...
How should I build my AJAX object for that simple purpose, and how should I integrate it?
Do I need to use forms at all?
I don't post anything to DB, just query it and print out data...
Thanks!!

How can i add a "like" button in a Django class ListView

I am pulling my hair out trying to add a "like" button in my siteĀ“s post app, but as i want to add it in a ListView that contains the rest of the posts entries and everyone has the option to be commented I have added a Formixin to do so, so, now i cannot add another form for the like button as it would mean two posts requests....so I am not finding a clear solution... I have read here and there about using AJAX or Json techs but as im new programing im kind of stuck in it... has anyone any tip to offer?
While using AJAX (javascript XHR requests) would be the proper way so the page doesn't need to be refreshed when just clicking a like button, you can do it without AJAX.
HTML
On the HTML side of things, you can have multiple forms (<form>), one for each post, which have a hidden input field that's the post's id. You have set that explicitly in the HTML template, e.g.
{% for post in post_list %}
<h3>{{ post.title }}</h3>
<p>{{ post.summary }}</p>
<form method="post">
{% csrf_token %}
<input type="hidden" value="{{ post.id }}" name="{{ form.id.html_name }}">
<input type="submit">Like</input>
</form>
{% endfor %}
So basically you're reusing the form multiple times, changing the "value" attribute to match the post.
Django Form
Adding the FormMixin to your view is the right step, just use the form_class to a custom LikeForm with just one field that's an IntegerField called id.
View
By adding the FormMixin you get the form_valid() method, which you'll want to override to save the like:
def form_valid(self, form):
id = form.cleaned_data['id']
try:
post = Post.objects.get(id=id)
except Post.DoesNotExist:
raise Http404
post.likes.add(self.request.user) # assuming likes is a m2m relation to user
return redirect('post_list') # this list view
Hopefully I am not so late, I had similar challenges trying to implement the same functionalities on my website.
I came to realize that each button id should be unique (Preferably the post id if blog), but the classes can be the same.
I was able to solve it. Here is an article I wrote on medium recently on the steps I followed to so get this working you can check it out here

Have url with pk or id to redirect to update page in Django error message

I've created an app, and on the CreateView page, the Submit button works fine to create a new S Reference. I also created an error message if the input value matches an existing Reference. I created button in the error message part and tried to link it to update the page to update these reference fields, like primary contact. I tried many options but have not got right code for the argument with pk or id to get individual record update page.
this is the url in error message.
I tried quite few pk, id options, none of them works.
'pk'=self.pk;
{'pk'=self.pk};
object.id
some code as below
models.py
class LNOrder(models.Model):
reference_number = models.CharField(max_length=15,blank=True, null=True, unique=True, error_messages={'unique':"This reference already exists."})
primary_contact = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
urls.py
urlpatterns = [
path('lfcnotifier', LNCreateView.as_view(), name='lnorder_create'),
path('lfcnotifier/<int:pk>', LNDetailView.as_view(), name='lnorder_detail'),
path('lfcnotifier/<int:pk>/update/', LNUpdateView.as_view(), name='lnorder_update'),
]
template
<div class="input-group mb-3">
<div class="input-group-prepend w-225px">
<label class="input-group-text w-100">S Reference</label>
</div>
<input name="reference_number" type="text" class="form-control" placeholder="Enter your S Reference"/>
<button class="btn btn-primary cardshadow " data-toggle="tooltip" title="Click to submit" style="width:200px;" type="submit">submit</button>
{%for field in form %}
{% for error in field.errors %}
{{ error }} Update Request
{% endfor %}
{% endfor %}
Views.py
class LNCreateView(SuccessMessageMixin,LoginRequiredMixin,CreateView):
model = LNOrder
template_name = 'lfcnotifier/lnorder_create.html'
form_class = LNOrderForm
def form_valid(self, form):
form.instance.created_by = self.request.user
return super().form_valid(form)
I expect when users click on Update Request button, it'll open the update page to edit the individual reference.
but I got message "Could not parse the remainder: '=self.pk' from ''pk'=self.pk'".
I get slightly different messages when I try the above different options.
I would like to have the right code for the URL to update the page when the Update Request button is clicked.
Thanks,
Additional background, I only put some of template code here to save space. They are in form section. If I use the following code
Update Request
instead of
Update Request
it can open the full list page without issue. I can go to update page from full list page without issue. But I want to open update page from here directly other than have one more step.
This is all kinds of confused.
For a start, you can't use a string on the left-hand side of an expression, either in pure Python or in Django templates.
But secondly, you don't have anything called self there. What you do have would be passed from the view; however it's not clear from the code you have posted which actual view this is. It doesn't seem to be that CreateView, because you are linking to the update. But assuming it's actually the LNDetailView, and assuming that that actually is a DetailView, you have access to the current object in the template exactly as object.
So you would do:
{% url 'lnorder_update' pk=object.pk %}
However again, this makes no sense to actually do. You can't submit a form via an a. You need a <form> element with a button.

Django button in html template creates error that I can't solve

my code is simple but I admit I have taken it from the internet.
I want to update a model with a button click. Which model, it is chosen by the variable. So I have this html code:
<form action="{% url 'reception:update_status' slug=name %}" method="POST">
{% csrf_token %}
<input type="submit" value="has arrived">
</form>
This code is in url.py
re_path('update_status/(?P<slug>[-a-zA-Z0-9_]+)$', views.update_status, name='update_status'),
and in views.py
def update_status(request, slug):
if request.method == 'POST':
p = MyModel.objects.filter(name=slug)
p.status = 'is waiting'
p.update()
return redirect(request, 'home')
Now with the code like this it comes back with the following error when I click on the button!
Reverse for '<WSGIRequest: POST '/update_status/Name10'>' not found. '<WSGIRequest: POST '/update_status/Name10'>' is not a valid view function or pattern name.
and I have no clue what this means. Please help?
Thanks
For regex patterns in Django 2.0, you need to use re_path, instead of path for your url.
I solved this problem with pk rather than slugs.
I would recommend everyone who is new to Django to create an id field for every Model. Because that can then be used to pass parameters very easy. Slug is more complicated and makes life unnecessarily difficult!

Django Formview Won't Validate

Django newbie here. I recently implemented a simple search with Django. I user specifies data in search bar, search is executed. I was able to determine today how to get the search to be null if user clicks on empty search bar. What I'm really trying to accomplish is to implement error logic so that the user has to specify data in the search bar. This has been very straight forward with all of the other views, but the search is a bit trickier, for me anyway. I have done several SO searches today, and determined that my HTML get method is ok for a search, but it may be causing some problems with the FORMVIEW that I am using. I have also tried to override POST and GET for the FORMVIEW, but can't seem to get it to work. I want to stick with CLASS BASED VIEWS, so I am using FORMVIEW. Here is my code....
My HTML
<form method="GET" autocomplete=off action="{% url 'Book:book_request_search_results' %}" >
<div>
<h1 class="title">Book Request Search</h1>
</div>
{{ form.non_field.errors }}
<div class="section">
<input type="search" class="name2" name="q">
</div>
<div class="section">
<input type="submit" id="" class="submit6" value="Search">
</div>
My VIEWS.PY
class BookRequestSearchView(LoginRequiredMixin,FormView):
form_class = BookRequestSearch
template_name = 'store/Book_request_search.html'
success_url = reverse_lazy('store:book_request_search_results')
def form_valid(self, form):
self.kwargs['q'] = form.cleaned_data['q']
if self.request.GET.get('q'):
pass
else:
raise forms.ValidationError("Enter data")
return super(BookRequestSearchView, self).form_valid(form)
My FORMS.PY
class BookRequestSearch(forms.Form):
q = forms.CharField(required=True)
def __init__(self, *args, **kwargs):
super(BookRequestSearch, self).__init__(*args, **kwargs)
I also tried to add a clean method to my form but that doesn't seem to work either...
def clean(self):
search = self.initial['q']
if search:
pass
else:
raise forms.ValidationError("Enter data")
return self.cleaned_data
I've been scanning most of the afternoon and can't seem to find a way to trigger validation on the FORMVIEW to trigger an error on the search bar. Any help would be appreciated. I've seen many different FORMVIEW articles, but none of them have helped me understand what I'm doing wrong and why this isn't working. The way the code is now, it works, but it doesn't prevent user from clicking on search and then triggering essentially an empty query. I'm trying to prevent that by forcing the user to put something in the box if they try to search with no criteria. Thanks in advance for any direction.
I was wrong on saying that it's only possible with javascript.
It's so simple as adding the required attribute to your input form, so the browser catches the empty error.
<form>
<input type="search" required><!-- added the required attribute-->
</form>