I'm fairly new to Django, and am working on a project where I use forms to get a user to enter a stock symbol and then using urllib I pull the data from Yahoo and return it. However, I'm not sure how to do this.
Here is my forms.py:
class Search(forms.Form):
search = forms.CharField()
Here is my views.py:
def search(request):
context = RequestContext(request)
if request.method == 'POST':
search = Search(data=request.POST)
if search.is_valid():
success = True
subject = search.cleaned_data['search']
sourceCode = urllib2.urlopen("http://finance.yahoo.com/q/ks?s="+subject).read()
pbr = sourceCode.split('Price/Book (mrq):</td><td class="yfnc_tabledata1">')[1].split('</td>')[0]
else:
print search.errors
else:
search = Search()
return render_to_response('ui/search.html', {"search":search}, context)
This is the form I use to get users input (it has some bootstrap styling):
<form class="navbar-form navbar-right" role="search" action="/search/" method="POST">
{% csrf_token %}
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter stock symbol" name="search">
</div>
<button type="submit" value="Save" class="btn btn-primary">Submit</button>
</form>
And finally here is my search.html file where I'd like to display the data:
{% extends 'ui/base.html' %}
{% block title %} {{ search.search.value|upper }} {% endblock %}
{% block body_block %}
<div class="container">
<h2>{{ search.search.value|upper }}</h2>
<h2>{{ I'd like to display 'pbr' (as definied in my views.py) here }}</h2>
{% endif %}
</div>
{% endblock %}
What I's like to do is take the pbr from my views.py and display it in my templates. Anyone know if I can do this? Thanks.
Build a result dictionary in your view as:
result = {}
if search.is_valid():
success = True
subject = search.cleaned_data['search']
sourceCode = urllib2.urlopen("http://finance.yahoo.com/q/ks?s="+subject).read()
pbr = sourceCode.split('Price/Book (mrq):</td><td class="yfnc_tabledata1">')[1].split('</td>')[0]
result['pbr'] = pbr
result['search'] = search
and return this result as:
return render_to_response('ui/search.html', {"result":result}, context)
In your template now you can access the pbr as:
<h2>{{ result.search.value|upper }}</h2>
<h2>{{ result.pbr }}</h2>
Related
I'm trying to get just a basic model and form to show up with mongoengine and WTF forms, and following the basic instructions from the website aren't working for me. I'm sure it's something simple that is missing, but I've never used flask, mongoengine, or WTFforms, so I'm sort of
Here is my schema definition in models.seed
class PlandoSeed(db.Document):
def __init__(self, preset:str='open', num_players:int=2, num_plants:int=1, **entries: dict):
self.__dict__.update(entries)
self.preset = preset
self.num_players = num_players
self.num_plants = num_plants
preset: db.StringField()
num_players: db.IntField(min=2, max=6)
num_plants: db.IntField(min=1, max=6)
seeds :List[PlandoSeed] = [PlandoSeed('standard',2,2), PlandoSeed('open',4,1), PlandoSeed()]
PlandoSeedForm = model_form(PlandoSeed)
Then this is the route/view that I created in views.py:
#app.route('/seeds/create', methods = ['GET', 'POST'])
def create_seed():
form = PlandoSeedForm(request.form)
if request.method == 'POST' and form.validate():
# todo
redirect('/seeds/')
return render_template('new_seed.jinja', form=form)
Finally, this is my 'new_seed.jinja' template:
{% extends 'base.jinja' %}
{% block content %}
<h1>{% block title %} Create Seed {% endblock %}</h1>
<form method="POST" action="/seeds/create/">
{{ form.csrf_token }}
{% for field in form %}
{{ field }}
{% endfor %}
<input type="Submit" value="Go">
</form>
{% endblock %}
My expectation is that the Create Seed page will have a form with the default input for a text field and integer fields. However, the only field that is in the form object in the jinja template is the CSRF token.Here is what it looks like.
And this is the generated HTML for the form:
<h1> Create Seed </h1>
<form method="POST" action="/seeds/create/">
<input id="csrf_token" name="csrf_token" type="hidden" value="ImZkNzMwMTE1NDJmNDM4NmFjY2EwZDU1ODBjNGJiMjZiMDBhNzFmZGQi.YsRdgg.I8r_Q5RXpmV-r2AzlUNAQ0le7XY">
<input id="csrf_token" name="csrf_token" type="hidden" value="ImZkNzMwMTE1NDJmNDM4NmFjY2EwZDU1ODBjNGJiMjZiMDBhNzFmZGQi.YsRdgg.I8r_Q5RXpmV-r2AzlUNAQ0le7XY">
<input type="Submit" value="Go">
</form>
I have a form that is based on a ModelForm in my forms.py. I initially get the blank form as expected, however when filling out the form and hitting submit nothing happens. I am not sure where I am going wrong.
views.py
def add_customer(request):
# print(customer_form)
# print(customer_form.errors)
print(request.method)
print(request.POST)
customer_form = CustomerForm(request.POST or None)
if customer_form.is_valid() and request.method == 'POST':
form = CustomerForm(request.POST)
form.save()
return redirect('AdminPortal:customers')
print('posted')
else:
print('failing')
context = {'customer_form': customer_form,}
return render(request, 'add_customer.html', context=context)
urls.py
path("customers/", views.customers, name="customers"),
path("customers/customer/<int:id>/", views.customer, name="customer"),
path("add_customer/", views.add_customer, name="add_customer"),
forms.py
class CustomerForm(forms.ModelForm):
class Meta:
model = AppCustomerCst
fields = ('is_active_cst', 'name_cst', 'address_1_cst', 'address_2_cst', 'address_3_cst',
'city_cst', 'state_cst', 'zip_cst', 'country_cst', 'salesrep_cst', 'type_cst',
'is_allowed_flat_cst', 'iddef_cst', 'balance_notify_cst', 'receive_emails_cst',
'contact_domain_cst'
)
add_customer.py [form portion]
<form method="post" action='AdminPortal:add_customer'>
{% csrf_token %}
{{ customer_form }}
<button type="button" value="submit">Submit</button>
<button type="button" value="cancel">Cancel</button>
</form>
It looks like the form doesn't know where to post.
You need to turn it into a django url template tag. So I'd do something like this for your form;
<form method="post" action='{% url "AdminPortal:add_customer" %}'>
{% csrf_token %}
{% if form.non_field_errors %}
{{ form.non_field_errors }}
{% endif %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
<button type="button" value="submit">Submit</button>
<button type="button" value="cancel">Cancel</button>
</form>
To find what's happening in your view I'd recommend simplifying the logic somewhat so that it's more inline with the docs here; https://docs.djangoproject.com/en/3.1/topics/class-based-views/intro/#handling-forms-with-class-based-views
Because you're doubling up the check for post & valid, I suspect you're never seeing the validation errors because they'd only come from that block of code. So change your view to be something like this and if you updated your template as above you should see some errors;
def add_customer(request):
if request.method == 'POST':
form = CustomerForm(request.POST)
if form.is_valid():
form.save()
return redirect('AdminPortal:customers')
else:
form = CustomerForm()
return render(request, 'add_customer.html', {'customer_form': form})
I found my error in the HTML Template.
I had:
<button type="button" value="submit">Submit</button>
<button type="button" value="cancel">Cancel</button>
Once Updated to:
<input type="submit" value="submit">Submit</input>
<input type="submit" value="cancel">Cancel</input>
The form posted properly as expected.
consider this model on Django:
class My_model(models.Model):
my_choices = { '1:first' 2:second'}
myfield1=CharField()
myfield2=CharField(choices=my_choices)
Then on my form:
class My_form(forms.ModelForm):
class Meta:
model = My_model
fields = ['myfield1', 'myfield2']
My views:
def get_name(request):
if request.method == 'POST':
form = My_form(request.POST)
if form.is_valid():
return HttpResponseRedirect('/')
else:
form = My_form()
return render(request, 'form/myform.html', {'form': form})
On my template:
{% extends "base.html" %}
{% block content %}
<form action="/tlevels/" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
{% endblock %}
On my base.html, I will load this template like this:
{% extends "base.html" %}
{% block content %}
{% load crispy_forms_tags %}
<div class="p-3 mb-2 bg-info text-white" style="margin-left:20px; margin-bottom:20px;">Status</div>
<div class="form-row" style="margin-left:20px; margin-bottom:20px; margin-top:20px;">
<div class="form-group col-md-6 mb-0">
{{ form.myfield1|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.myfield2|as_crispy_field }}
</div>
</div>
<input type="submit" class="btn btn-primary" value="Submit" style="margin-left:20px;">
</form>
{% endblock %}
What I want, is to have 2 other different templates, with whatever difference on them, and load them depending on the choice made on the ChoiceField, I guess that one way could be on the view, by adding some kind of conditional, and load a different template (html file).
Any ideas?
It is possible to use {% include %} with a variable.
def some_view_after_post(request):
# ... lookup value of myfield2 ...
return render(request, "path/to/after_post.html", {'myfield2: myfield2})
The in the after_post.html template:
<!-- include a template based on user's choice -->
<div class="user-choice">
{% include myfield2 %}
</div>
You'll want to make sure there is no possible way the user can inject an erroneous choice. For example, make sure the value of myfield2 choice is valid before adding it to the context.
I have started learning django, but I can't understand how to render form.
This is form.py I have made.
from django import forms
class TweetForm(forms.Form):
text = forms.CharField(widget = forms.Textarea(attrs = {'rows' : 1, 'cols' : 85}), max_length = 160)
country = forms.CharField(widget = forms.HiddenInput())
This is code snippet in views.py.
from .forms import TweetForm
class Profile(View):
def get(self, request, username):
params = dict()
user = User.objects.get(username = username)
tweets = Tweet.objects.filter(user = user)
params["user"] = user
params["tweets"] = tweets
form = TweetForm
return render(request, 'profile.html', {'params' : params, 'form' : form})
This is html file and it must render form I have made.
{% extends "base.html" %}
{% block content %}
<div class="row clearfix">
<div class="col-md-12 column">
<form method="post" action="post/">
{% csrf_token %}
<div class="col-md-8 col-md-offset-2 fieldWrapper">
{{ form.text.errors }}
{{ form.text }}
</div>
{{ form.country.as_hidden }}
<div>
<input type="submit" value="post">
</div>
</form>
</div>
<h3> </h3>
<div class="col-md-12 column">
{% for tweet in tweets %}
<div class="well">
<span>{{ tweet.text }}</span>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
When I issue command(run server), browser don't render form without any exception.
I think there is a problem in views.py file, But I can't find it.
How can I send form parameter to Template(.html file) and render form in result?
You didn't instantiate the form.
You need to instantiate the form, for rendering in a template, like this,
form = TweetForm()
Note:
The params variable is already a dict(), you could just add form into the params like this,
params['form'] = form
Then, render the template with context as params,
render(request, 'profile.html', params)
I am new to python and django and I was following a tut with major errata. right now I am trying to get the results page to display my results. This is not my code, it's from a tutorial. Here is my code.
my views.py
def post_search(request):
form = request.GET.get('q')
results = SearchQuerySet().models(Post).filter(content=form)
# count total results
total_results = results.count()
template = 'blog/post/search.html',
context = {
'form': form,
'results': results,
'total_results': total_results
}
return render(request, template, context)
my search.html
{% extends "blog/base.html" %}
{% block title %}Search{% endblock %}
{% block content %}
{% if request.GET %}
<h1>Posts containing "{{ form.query }}"</h1>
<h3>Found {{ total_results }} result{{ total_results|pluralize}}</h3>
{% for result in results %}
{% with post=result.object %}
<h4>{{ post.title }}</h4>
{{ post.body|truncatewords:5 }}
{% endwith %}
{% empty %}
<p>There are no results for your query.</p>
{% endfor %}
<p>Search again</p>
{% else %}
<h1>Search for posts</h1>
<form action="." method="get">
<div>
<div class="input-group">
<input type="text" class="form-control" autocomplete="off" name="q" id="search" placeholder="search" value="{{ request.GET.q }}">
<span class="input-group-btn">
<button type="submit" class="btn btn-default">search</button>
</span>
</div><!-- /input-group -->
<ul class="list-group" id="search-results" style="margin: 5px 0 0 0; width: 325px">
</ul>
</div>
</form>
{% endif %}
{% endblock content%}
my post_text.txt
{{ object.title }}
{{ object.tags.all|join:", " }}
{{ object.body }}
search_indexes.py
from haystack import indexes
from .models import Post
class PostIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
publish = indexes.DateTimeField(model_attr='publish')
# title_auto = indexes.EdgeNgramField(model_attr='title')
# content_auto = indexes.EdgeNgramField(model_attr='content')
def get_model(self):
return Post
def index_queryset(self, using=None):
"""Used when the entire index for model is updated."""
return self.get_model().objects.all()
the only thing that shows on the page after I run a search is
Posts containing ""
Found 1 result
Search again
and if I do this
{{results}}
it returns this
[<SearchResult: blog.post (pk='2')>]
where it says post containing a name will show
found results returns a number which lets me know that the results are working
any and all help or guidance in the right direction is greatful. Tried to read the docs. They seem so vague to me. and as I said I am a novice.and there are only video on the topic and that with frank hibbert and he uses it with ajax