Can't display map on template using PointField django - python

Can we display a map on a template using django PointField?
I have a model with one PointField and then after creating a model form, I want to display the map in my template using that form.
View
def map_view(request):
form = ShopForm()
context = {
'form' : form
}
return render(request, 'ads/map.html', context)
Template
<html>
<head>
</head>
<body>
<div>
<form method="post">
{{ form }}
<input type="submit" >
</form>
</div>
</body>
</html>
I was wondering is it possible to display the map using that or do I need to something extra.

I was also having the same question and thankfully I got the right way of doing it.
Anyone who's facing this issue can follow this link
The tutorial is divided into three parts.
REMEMBER:
When you reach to the 2nd part and everything is done and you're writing python manage.py runserver
-in your template include all these
{% load leaflet_tags %}
{% leaflet_css %}
{% leaflet_js %}
Place this within your {% block content %} {% endblock content %} otherwise you'll end up rendering nothing

Have you tried using the following part of the documentation on your form?
https://docs.djangoproject.com/en/2.2/ref/contrib/gis/forms-api/#widget-classes:
from django.contrib.gis import forms
class ShopForm(forms.Form):
point = forms.PointField(widget=
forms.OSMWidget(attrs={'map_width': 800, 'map_height': 500})
)

Related

How to send object from detail view to another view in Django?

I have a detail view that uses a Quiz object to display data stored in that object, like title and author. I want to have a button that links to a new page that displays different data from the same object. I don't know how to pass this data/object.
I can render the view and pass it the context of a specific quiz using an id but I want the id to change to be the id of the object from the initial page.
#assessement view
def assessment(request):
context = {
'quiz':Quiz.objects.get(id=1),
}
return render(request, 'quiz_app/assessment.html', context)
#detailview template for quiz
{% extends "quiz_app/base.html" %}
{% block content %}
<article class="quiz-detail">
<h1>{{ object.title }}</h1>
<h2>{{ object.question_amount }} Questions</h2>
<a class="btn" href="{% url 'quiz-assessment' %}">Start Quiz</a>
</article>
{% endblock content %}
#assessment template
{% extends "quiz_app/base.html" %}
{% block content %}
<h2>Assessment</h2>
<h2>Title is {{ quiz.title }}</h2>
{% endblock content %}
Then you should make another view for url quiz-assessment and pass the quiz pk as you did above in your assessment view.
def quiz_assessment(request,pk):
quiz = Quiz.objects.get (pk=pk)
return render (request,'assessment_template', {'quiz':quiz}
And in your url,pass the quiz id like this:
path ('<int:pk>/quiz/assessment /',views.quiz_assessment,name='quiz_assessment')
And in your template you can give url like this:
< a class="btn" href="{% url 'quiz_assessment' object.pk %}>
As suggested in the comments by #Robin Zigmond, you can do like this.
#assessement view
def assessment(request, qid):
context = {
'quiz':Quiz.objects.get(id=qid),
}
return render(request, 'quiz_app/assessment.html', context)
In the HTML file
#detailview template for quiz
{% extends "quiz_app/base.html" %}
{% block content %}
<article class="quiz-detail">
<h1>{{ object.title }}</h1>
<h2>{{ object.question_amount }} Questions</h2>
<a class="btn" href="{% url 'quiz-assessment' qid=object.id %}">Start Quiz</a>
</article>
{% endblock content %}
and in your urls.py change as:
path('quiz_asswssment/?P<int:qid>/', views.assessment, name="quiz_assessment")
Besides, what SammyJ has suggested, You can use the django sessions library or the django cache framework. You can temporarily store the information you need for the next view and access it whenever you want to.
In what Sammy J had suggested, you will always to have make sure that the queryset is passed in the context, otherwise it will not be rendered.
def assesment(self, request, id):
q = Quiz.objects.get(pk=id)
request.session["someData"] = q.name
request.session["qAmount] = q.amount
In your template file
<p>The title is : {{request.session.title}} and the amount is {{request.session.qamount}}
Note: Django sessions do not allow you to set a queryset as a session record, for that, you can use Django Cache framework.
Example
from django.core.cache import cache
cache.set('quiz', q)
getting cache -> cache.get('quiz')
Sessions framework docs : https://docs.djangoproject.com/en/2.2/topics/http/sessions/
Cache framework docs: https://docs.djangoproject.com/en/2.2/topics/cache/

Why is my flask form validation returning Not a valid choice?

I have been trying to figure out why my Flask form will not properly validate my select field choices even though the choices are coming from the select field options.
My assumption is that the select option when passed back from the server is unicode and is being compared to the choice which is a string, however, I thought coerce=str would fix that. I printed out the form data and request data which is the output below. Why isn't it working?
My code is attached below, removed csrf token key from the output dict. It seems like a very simple thing, but I can't figure it out.
forms.py
class PlatformForm(FlaskForm):
platform_options = [('test', 'Test'), ('test2','Test2')]
platforms = wtforms.SelectField('Platforms', choices=platform_options, coerce=str, validators=[DataRequired()])
views.py
#app.route('/', methods=['POST', 'GET'])
def index():
form = forms.PlatformForm()
if form.is_submitted():
print form.data
print request.form
if form.errors:
print form.errors
return render_template('home.html', form=form)
index.html
{% extends "base.html" %}
{% block content %}
<h4>Select a Platform</h4>
<form method="POST">
{{ form.csrf_token }}
<select class="custom-select" name="platform">
{% for value, text in form.platforms.choices %}<br>
<option value="{{ value }}">{{ text }}</option>
{% endfor %}
</select>
<button id="submit_inputs" type="submit" class="btn btn-default">Submit</button>
</form>
{% endblock %}
output
{'platforms': 'None'}
ImmutableMultiDict([('platform', u'test')])
{'platforms': [u'Not a valid choice']}
EDIT:
I figured out the problem. It's the way I'm creating the Select drop down through HTML and Jinja. Iterating through the choices and creating option tags doesn't seem to instantiate anything in the form data itself when passed back into Python. Changing that whole for loop to just
{{form.platforms}}
created a select drop down field that actually works.
You have a name mismatch. In the form, you named your select field platforms (plural). In the HTML, you use platform (singular).
I recommend that instead of manually rendering the fields in your template, you let WTForms generate the HTML for you. For the form label, you can use {{ form.platforms.label }}, and for the actual field {{ form.platforms() }}. You can pass any attributes you want to field to have as keyword arguments.
I think something might be going wrong because of the way you are rendering the form in your html file. If my hunch is right, try this:
{% extends "base.html" %}
{% block content %}
<h4>Select a Platform</h4>
<form method="POST">
{{ form.hidden_tag() }}
Select: {{ form.plaforms}}
{{ form.submit(class="btn btn-default") }}
</form>
{% endblock %}
and then try if form.validate_on_submit() in your views.py file
taken from this stack overflow answer by pjcunningham:
"validate_on_submit() is a shortcut for is_submitted() and validate().
From the source code, line 89, is_submitted() returns True if the form
submitted is an active request and the method is POST, PUT, PATCH, or
DELETE.
Generally speaking, it is used when a route can accept both GET and
POST methods and you want to validate only on a POST request."

Display all model data inside html page

I'm trying to build a website that has products and categories.
When you are on the page of a product, you can click a button to see a list of all the categories it falls under.
You can click another button, that appears on all pages, to see a list of all the categories overall.
In the html page see_all_categories, I wrote a simple block like this:
{% extends 'base.html' %}
{% load staticfiles %}
{% block content%}
{{Category.all}}
{% endblock content %}
I expect to see a messy printout of all the categories but I don't. It doesn't return an error, but it produces nothing, other than the base.html.
What am I doing wrong?
You want to display a list of the categories. I assume your Category model owns an attribute named "title" which is the representation of your Category.
If you're using Django template engine or Jinja2, you can make a for loop inside your template like this :
{% for cat in Category.objects.all %}
{{ cat.title }}
{% endfor %}
As a troubleshooting, I'd suggest you didn't pass your Category model to your template, that is not done automatically. You have to add your model to the context before rendering the template.
As mentionned in the comments, here is doc for template rendering with Django templates.
Django Template Guide
To add your model to the context you can follow this guide.
I don't intend to help you further because I lack of information and that may vary a LOT according to your settings. (Class Based views ? Function based views ? What kind of template are you using... And so on)
I figured out the solution after many long annoying hours of trying everything. I feel dumb but I want to spare the next guy the massive pain in the two-pack.
This is what I did:
In the Views.py, I changed the view function for this page FROM this:
def view_all_categories(request):
context = {'Category' : Category}
return render(request, 'store/see_all_categories.html', context)
TO this
def view_all_categories(request):
all_cats = Category.objects.all().order_by('id')
context = {'all_categories' : all_cats}
return render(request, 'store/see_all_categories.html', context)
and in the page see_all_categories.html itself, I changed it (from the question) TO this:
{% extends 'base.html' %}
{% load staticfiles %}
{% block content%}
{% for cat in all_categories %}
<p>{{ cat.name }}</p>
{% endfor %}
{% endblock content %}
And now it works!!

Write text under a form definition in python flask

I have a about page in my python flask website. I want to write some text under a form definition. My python app has a definition for the about page.
class Aboutpageshow(flask.views.MethodView):
def get(self):
return flask.render_template('about.html')
and linking
app.add_url_rule('/about',view_func=Aboutpageshow.as_view('aboutpage'),
methods=["GET"])
And the html page definition is as follows
{% extends "base.html" %}
{% block content %}
<h1>About</h1>
<form method= action="{{url_for('aboutpage')}}">
<p> my text here </p>
</form>
</br>
{% endblock %}
{% block nav %}
<li>back</li>
{% endblock %}
In this process I want to write the text in this form space.
class wtforms.fields.Field
Stores and processes data, and generates HTML for a form field.
I am not sure if you are talking about placeholders or help text, so i will say for both.
The WtForms Form field takes description as one of the parameter
which will work as helptext for you when you render forms.
Refer : http://wtforms.simplecodes.com/docs/0.6.1/fields.html
In order to use placeholders with jinja2 templates, you have to use
something like this in your jinja2 templates
{{ demo.render(placeholder="abc")|safe }}

django endless pagination(twitter style) not working - .endless_more class not in html but used in js

i am using django endless pagination . its working normally that just shows the numbers at the bottom .
but, i tried to integrate twitter style into it:
http://django-endless-pagination.readthedocs.org/en/latest/twitter_pagination.html#pagination-on-scroll
I have followed exactly but didnt work .
When I looked at the js code, i have seen they have used .endless_more in js class, but the generated html file has only two classes for links :
1)endless_page_current
2)endless_page_link
but they used a.endless_more in js.
Can you tell me the correct way to implement?
Thanks
Views :
from endless_pagination.decorators import page_template
#page_template("my_index_page.html")
def myview(request,template='my_index.html', extra_context=None):
data = {}
if extra_context is not None:
data.update(extra_context)
myobj = Myobj.objects.all()
data['myobj'] = myobj
return render_to_response(template, data, context_instance=RequestContext(request))
Template :
my_index.html
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="{{ STATIC_URL }}js/endless.js"></script>
<script src="{{ STATIC_URL }}js/endless_on_scroll.js"></script>
{% include page_template %}
my_index_page.html
{% load templatetags %}
<center>
<div>
{% load endless %}
{% paginate myobj %}
{% for obj in myobj %}
{{ obj.name }}
{% endfor %}
{% show_pages %}
</div>
<center>
Here, I seriously beleive that i need to add some classes like endless_more , which the django-endless-documentation missed.
i'm using that on my portal, and it seems fine your code, you just missed one thing
{% show_more %}
that's what actually enables the twitter-style infinite pagination
edit here:
you may want to add this too:
<script type="text/javascript" charset="utf-8">
var endless_on_scroll_margin = 20;
</script>
where "20" is the number of pixels (from the bottom of the page) that triggers the scrolling
you may want to try more than one value till you get the perfect one for your project
see here and here

Categories