Hi I have created a Flask admin interface. In one of the field(column), I would like to include a hyperlink.
class workout(db.Model):
equipment = db.Column(db.String(100))
place = db.Column(db.String(100))
image = db.Column(db.Text)
or using Jinja2 macro in template:
I have to create a view which should include the above columns as well as I have to format the image column in the view.
I am really not so sure of how to create the view for the above mentioned custom class model.
from flask_admin.model.template import macro
class WorkoutView(ModelView):
in _macros.html file.
{% macro render_image() %}
Upload images
<script src="https://widget.cloudinary.com/global/all.js" type="text/javascript"></script>
<script type="text/javascript">
document.getElementById("upload_widget_opener").addEventListener("click", function() {
cloudinary.openUploadWidget({ cloud_name: 'mycloudname', sources: [ 'local', 'url', 'camera', 'image_search',
'facebook', 'dropbox', 'google_photos' ], upload_preset: 'myuploadpreset'},
function(error, result) { console.log(error, result) });
}, false);
</script>
{% endmacro %}
IF I run the _macros.html file, it is good and I am getting the hyperlink as expected.
Issue : I am not getting the hyperlink in the column which I formatted when I try to import the macros from _macros.html file
Is there any issue with my syntax in _macros.html or in app.py file ?
I think you are misuse SQLAlchemy and Flask-Admin. CustomModel class inherit from db.Model from SQLAlchemy and CustomModelView class inherit from ModelView from Flask-Admin to control the behavior of that Model in Flask-Admin. You can achieve your purpose as follows:
Use form_widget_args to add id attribute to form field;
Inherit create.html & edit.html to add javascript.
class ExampleModelView(ModelView):
# ...
edit_template = "admin/edit.html"
create_template = "admin/create.html"
form_widget_args = {
"image": {
"id": "cloudinary"
}
}
# ...
# template inherit. "edit.html" is same as "create.html" except the first line.
{% extends "admin/model/create.html" %}
{% block tail %}
{{ super() }}
<script src="https://widget.cloudinary.com/global/all.js" type="text/javascript"></script>
<script type="text/javascript">
# js code to upload image and return response
</script>
{% endblock %}
Related
I refer to the following posts:
Reload table data in Django without refreshing the page
Django dynamic HTML table refresh with AJAX
Despite the two post and nice answers, I am still struggling to construct a minimal working example for dynamic HTML pages resorting to Django and AJAX.
I have to following code:
models.py
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^get_more_tables', views.get_more_tables, name='get_more_tables')
]
views.py
from django.shortcuts import render
from .models import Question
def index(request):
a = Question.objects.order_by('-pub_date')
context = {'questions': a}
return render(request, 'polls/index.html', context)
def get_more_tables(request):
a = Question.objects.order_by('-pub_date')
context = {'questions': a}
return render(request, 'polls/get_more_tables.html', context)
index.html
<html>
<body>
<table id="_appendHere">
<tr><td> text </td></tr>
{% for a in questions %}
<tr><td> {{ a.question_text }} </td></tr>
{% endfor %}
</table>
</body>
</html>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
var append_increment = 0;
setInterval(function() {
$.ajax({
type: "GET",
url: "{% url 'get_more_tables' %}",
data: {'append_increment': append_increment}
})
.done(function(response) {
$('#_appendHere').append(response);
append_increment += 10;
});
}, 1000)
get_more_tables.html
{% for a in questions %}
<tr><td> {{ a.question_text }} </td></tr>
{% endfor %}
I have the following issues:
According to Console Error with Ajax: ReferenceError: $ is not defined, I need to set up the js.file in the js-script. If I do not do that, I get the "ReferenceError: $ is not defined" error. Why is that, in particular, as this is not necessary for the previous above mention posts?
If I run http://localhost:8000/polls/, nothing happens. I was assuming that, when I use
q2 = Question(question_text="What's up4?", pub_date=timezone.now())
q2.save()
by python manage.py shell, the entire internal database should be shown. However, nothing is happening. When I refresh the site by hand, all entries are shown.
The inspector console of Mozilla does not show any entry. The network console of Mozilla does show that /pools and the external js file is accessed. However, no continuous access in 1s intervals is shown (not sure if that should be the case).
Your HTML is not valid, for a couple of reasons.
First, you put the script block outside the closing </html> tag. That means it's outside the document itself, and may not be read by the browser.
More importantly, you haven't got your code inside a proper script element. You have an opening tag, but you use that to reference the external jQuery library via the src attribute. You don't have a closing tag at all
You need to put the jQuery reference in its own element, and use proper opening and closing tags for your own script.
<html>
<body>
<table>
...
</table>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
var append_increment = 0;
setInterval(function() {
$.ajax({
type: "GET",
url: "{% url 'get_more_tables' %}",
data: {'append_increment': append_increment}
})
.done(function(response) {
$('#_appendHere').append(response);
append_increment += 10;
});
}, 1000)
</script>
</body>
</html>
You have to externalyze your jquery in another file (without any tags, just the jquery). And add a ready function:
$(document).ready(function(){
// Your JS code here
});
In the html, do as follow:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
<script src="<relative_path_to_your_js>">
The route /polls/ doesn't exist. So nothing happens. You only have routes / and /get_more_tables defined.
I did not understand the last question, what do you enter in the Interactive Console ? (After entering ./manage.py shell)
I want to show a simple pop-up banner based on if a cookie is present or not. This is the python code I have
consent_cookie_str = self.request.cookies.get('consent')
if not consent_cookie_str:
// show banner here
What is the best way to show the banner if the cookie isn't present? Passing parameters into my jinja template?
Thanks
You can create a template like this:
<html>
<body>
<h1>Welcome!</h1>
<script type="text/javascript">
$(document).ready(function() {
{% if show_alert %}
alert('You have not given consent!');
{% endif %}
});
</script>
</body>
</html>
And call it from your handler like this (using webapp2):
consent_cookie_str = self.request.cookies.get('consent')
show_alert = consent_cookie_str is None
template_values = dict(show_alert=show_alert)
template = JINJA.get_template("page.html")
self.write_html(template.render(template_values))
If you are using Flask or something else, should be straightforward to modify this to work for you.
Before you mark this as a duplicate to the most famous django datepicker question on SO, hear me out. I have gone through all the questions in the first ten pages of the search results, but no one seems to be explaining anything from the beginning.
What I am looking for is the most simple way to have a datepicker on my form, I don't know if the most simple way is importing it from Admin or using an existing jQuery thing, but whatever it is, can someone please explain step by step like you would do to a baby? This, I believe will help any new programmer like me out there who's looking to learn. This is what I have so far.
My Form:
class SampleForm(forms.Form):
date_of_birth = forms.DateField(label='Enter Date')
My View:
def dlp_test(request):
form = SampleForm()
return render(request, 'dlp_test.html', {'form': form})
My Template:
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
This is the most simple setup anyone can start from, how do I take it from here? When someone clicks on the datefield in the HTML, I want a calendar to pop up so that they can select a date.
If achieving this requires me to have locally stored JS or jQuery files, I'd prefer the URL be embedded in the HTML, rather than downloading and then mentioning the source, because my paths are messed up right now. You can assume that I don't have anything else downloaded or installed other than Django and Python.
This is probably somewhat hacky, but when I want to use the jQueryUI datepicker for a specific form field I do this:
Add the stylesheet in the <head> of my template:
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
Add the javascript file at the end of my template:
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
crossorigin="anonymous"></script>
The field of your form with which you want to use the datepicker will have a specific ID. In your case it will probably be id_date_of_birth. So you can select the date of birth textbox by ID and apply the datepicker to it (this assumes you are also using jQuery):
<script>
$(document).ready(function() {
$('#id_date_of_birth').datepicker({firstDay: 1,
dateFormat: "dd/mm/yy",
defaultDate: "16/06/2017",
minDate: "16/06/2017",
maxDate: "25/06/2017"});
});
</script>
Note that this snippet has to come AFTER you include the javascript file. Also, I am setting some defaults you may not need - the simplest way to make it work would be:
<script>
$(document).ready(function() {
$('#id_date_of_birth').datepicker();
});
</script>
Hopefully that helps you out!
I searched and struggled a lot to get the problem fixed
I recommend
this source.
In forms.py:
# Create custom widget in your forms.py file.
class DateInput(forms.DateInput):
input_type = 'date'
In the same forms.py:
# Form class in forms.py
class LastActiveForm(forms.Form):
"""
Last Active Date Form
"""
last_active = forms.DateField(widget=DateInput)
This works perfectly with formset too.
In the template file:
{ form.as_p }
# Only without any external libraries or add-ons
This is what I added to my template and it is working now. To someone in the future looking for an answer, here it is. Although, I must tell you that this might not scale well on large projects, you might have to use this function everywhere or something like that, but for now, this works for me.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Datepicker - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<form action="." method="post">
{% csrf_token %}
{{form.as_p}}
<p>Date: <input type="text" id="datepicker"></p>
<input type="submit" value="Submit" />
</form>
<script>
$( function()
{
$( "#id_date_of_birth" ).datepicker();
$( "#datepicker" ).datepicker();
} );
</script>
</body>
</html>
I recently needed to add a date field with a datepicker to a form. I did this quick so please forgive a typo or 3 :)
The Jquery is referencing an id "#id_date_of_birth", but it would be better practice to make this a class like "datechooser" so you can use it on any form instead of just the "date_of_birth" form field.
Models.py
from django.db import models
class Sample(models.Model):
date_of_birth = models.DateTimeField(help_text='date_of_birth', null=True)
Forms.py
from django.forms import ModelForm, widgets, DateTimeField, DateField, DateInput
class SampleForm(ModelForm):
date_of_birth = DateTimeField(widget = DateInput(format='%Y-%m-%d'),
input_formats=('%Y-%m-%d',),
required=False)
class Meta:
model = Sample
fields = ["date_of_birth",]
Views.py
from django.views import generic
from sample.models import Sample
from sample.forms import SampleForm
def dlp_test(request):
form = SampleForm()
form = SampleForm(initial={'date_of_birth': timezone.now().date()}) # Set an initial value for today
return render(request, 'dlp_test.html', {'form': form})
dlp_test.html
{{ form.date_of_birth }}
{{ form.date_of_birth.errors }}
Datepicker via Jquery for a form field
Header.html
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
$( function() {
$( "#id_date_of_birth" ).datepicker({
dateFormat: 'yy-mm-dd',
changeMonth: true,
changeYear: true
});
});
This is what i do to get datepicker in django forms.
install bootstrap_datepicker_plus by pip command.
pip install django-bootstrap_datepicker_plus
forms.py
from .models import Hello
from django import forms
from bootstrap_datepicker_plus import DatePickerInput
class CreateForm(forms.ModelForm):
class Meta:
model = Hello
fields =[
"Date",
]
widgets = {
'Date': DatePickerInput(),
}
settings.py
INSTALLED_APPS = [
'bootstrap_datepicker_plus',
]
I am using ChartIt and keep receiving the "Template does not exist" when trying to view the chart at the URL. The tutorial is being followed properly, but may have made a mistake somewhere. I am new to Django, so any help would be appreciated. The request to load the chart is working as the def is being called.
def in the views.py file.
def lineChart(request):
commitData = \
DataPool(
series=
[{'options': {
'source': TestCommit.objects.all()[:200]}, 'terms': ['author', 'author_time']}])
linechart = Chart(
datasource=commitData,
series_options=
[{'options': {
'type': 'line',
'stacking': False},
'terms': {
'author_time': [
'author_time']
}}],
chart_options=
{'title': {
'text': 'YAYs'},
'xAxis': {
'title': {
'text': 'Month number'}}})
return render_to_response({'testCommits.html': linechart})
testCommits.html
<head>
<!-- code to include the highcharts and jQuery libraries goes here -->
<!-- load_charts filter takes a comma-separated list of id's where -->
<!-- the charts need to be rendered to -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="http://code.highcharts.com/highcharts.js" type="text/javascript"></script>
<script src="/highcharts.js" type="text/javascript"></script>
{% load chartit %}
{{ linechart|load_charts:"container" }}
</head>
<body>
<div id='container'> Chart will be rendered here </div>
</body>
I noticed in their installation instructions they don't say to add 'chartit' to the INSTALLED_APPS in your settings file, but they did in their demo project. Have you done that?
Edit:
dan-klasson is correct. You need to specify the template to return. Your view should be returning the following:
return render_to_response('testCommits.html', {'linechart': linechart})
The dictionary is the context in that is passed to the template. The first argument is the template name, which in your case is testCommits.html.
You are getting this error because your Django does not know the location of your templates during template loading. Try this:
Go to your settings.py in your project root and specify your TEMPLATE_DIRS. The variable is already defined for you so simply list the path_to_your_dir. For example:
TEMPLATE_DIRS = (
"home/myname/path_to_templates"
)
Update your view to return properly as specified by other users:
return render_to_response('testCommits.html', {'linechart': linechart})
Let's imagine this model:
class ScribPart(models.Model):
name = models.CharField(max_length=50, unique=True)
text = models.TextField()
I'd like to attach a specific class to the field text and call a specific js file. So that the admin page would be like:
...
<script type="text/javascript" src="/static/js/mymarkup.js"></script>
...
<textarea id="id_text" name="text" class="mymarkup"></textarea>
...
How can I do that with a widget and/or custom admin form ?
To insert a <script> in an admin page the simplest thing to do is:
class ScribPartAdmin(model.ModelAdmin):
...
your normal stuff...
...
class Media:
js = ('/path/to/your/file.js',)
ModelAdmin media definitions documentation
Now to add the class attribute to the textarea I think the simplest way to do it is like this:
from django import forms
class ScribPartAdmin(model.ModelAdmin):
...
your normal stuff...
...
class Meta:
widgets = {'text': forms.Textarea(attrs={'class': 'mymarkup'})}
Overriding the default widgets documentation
I should add that this approach is good for a one shot use. If you want to reuse your field or JS many times, there's better ways to do it (custom widget for the field, with JS file specified if the JS is exclusively related to the field, extending template to include a JS file at many places).
You have to create a template, put it in templates/admin/change_form_scribpart.html with this content:
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block content %}
<script type="text/javascript" src="/static/js/mymarkup.js"></script>
{{ block.super }}
{% endblock %}
Also, don't forget to activate this new admin template in your ScribPart ModelAdmin:
class ScribPartAdmin(admin.ModelAdmin):
ordering = ...
fieldsets = ...
change_form_template = "admin/change_form_scribpart.html"
You can send your form with json pack and get(check) with this code
results = ScribPart.all()
for r in results :
if r.test == id_text:
self.response.out.write("<script type='text/javascript' src='/static/js/"+r.name+"mymarkup.js'></script>")