When using flask-admin, the list view for datetime fields is something like this: "2014-02-22 13:30:43".
I'd like to know if is possible to change this default view for something like this: "2014-02-22" or "2014-02-22 13:30".
thanks
Yes, you can set the column_type_formatters to define default formats. Also, you can set column_formatters to use custom formats only to one column in your list view.
https://flask-admin.readthedocs.org/en/latest/api/mod_model/#flask.ext.admin.model.BaseModelView.column_formatters
https://flask-admin.readthedocs.org/en/latest/api/mod_model/#flask.ext.admin.model.BaseModelView.column_type_formatters
from flask_admin.model import typefmt
from datetime import date
def date_format(view, value):
return value.strftime('%Y-%m-%d')
MY_DEFAULT_FORMATTERS = dict(typefmt.BASE_FORMATTERS)
MY_DEFAULT_FORMATTERS.update({
date: date_format
})
form_args = dict(
time = dict(validators=[DataRequired()],format='%Y-%m-%d %H:%M')
)
form_widget_args = dict(
time={'data-date-format': u'YYYY-MM-DD HH:mm'}
)
column_type_formatters = MY_DEFAULT_FORMATTERS
This will change the date format to 2014-02-22 13:30.
Related
I have a logging system, where users can log several symptoms for any given day. Im getting the date as slug in my url, but I need to validate it. Which one is best practice, and why?
make a validator function in the class view and use it there
add a hidden form field, and write a custom DateValidator for it?
You can define a path converter that will parse date objects. You can define a custom pattern with:
# app_name/converters.py
class DateConverter:
regex = '[0-9]{4}-[0-9]{2}-[0-9]{2}'
format = '%Y-%m-%d'
def to_python(self, value):
return datetime.strptime(value, self.format).date()
def to_url(self, value):
return value.strftime(self.format)
Next we can register that path converter [Django-doc] and work with:
from app_name.converters import DateConverter
from django.urls import path, register_converter
register_converter(DateConverter, 'date')
urlpatterns = [
# …
path('some/path/<date:date>/', some_view),
# …
]
This will pass a single date parameter to the view, which is a date object, you thus can work with:
def some_view(request, date):
# …
If you thus visit the path /some/path/2021-10-17, date will be a date(2021, 10, 17) object.
I want to get a row from a postgis table given a coordinate/point. With raw sql I do it with:
SELECT * FROM parcelas
WHERE fk_area=152
AND ST_contains(geometry,ST_SetSRID(ST_Point(342884.86705619487, 6539464.45201204),32721));
The query before returns one row.
When I try to do this on django it doesn't return me any row:
from django.contrib.gis.geos import GEOSGeometry
class TestView(APIView):
def get(self, request, format=None):
pnt = GEOSGeometry('POINT(342884.86705619487 6539464.45201204)', srid=32721)
parcelas = Parcelas.objects.filter(fk_area=152,geometry__contains=pnt)
#Also tried this
#parcelas = Parcelas.objects.filter(fk_area=pk,geometry__contains='SRID=32721;POINT(342884.86705619487 6539464.45201204)')
serializer = ParcelasSerializer(parcelas, many=True)
return Response(serializer.data)
Even with django raw query it fails although in this case it returns me an internal server error (argument 3: class 'TypeError': wrong type):
class TestView(APIView):
def get(self, request, format=None):
parcelas = Parcelas.objects.raw('SELECT * FROM parcelas WHERE fk_area=152 AND ST_contains(geometry,ST_SetSRID(ST_Point(342884.86705619487, 6539464.45201204),32721))')
for p in parcelas:
#Internal server error
print(p.id)
return Response('Test')
My model parcelas look like this:
from django.contrib.gis.db import models
class Parcelas(models.Model):
id = models.BigAutoField(primary_key=True)
fk_area = models.ForeignKey(Areas, models.DO_NOTHING, db_column='fk_area')
geometry = models.GeometryField()
class Meta:
managed = False
db_table = 'parcelas'
I don't know what I'm doing wrongly if someone has any idea.
EDIT:
If I print the raw query that django made:
SELECT "parcelas"."id", "parcelas"."fk_area", "parcelas"."geometry"::bytea FROM "parcelas" WHERE ("parcelas"."fk_area" = 152 AND ST_Contains("parcelas"."geometry", ST_Transform(ST_GeomFromEWKB('\001\001\000\000 \321\177\000\000C\224\335w\223\355\024A\350\303\355\0342\362XA'::bytea), 4326)))
Seems like django is not converting it to the correct srid (32721) but I don't know why
EDIT 2:
If in my model I specify the SRID it works correctly:
class Parcelas(models.Model):
geometry = models.GeometryField(srid=32721)
The problem is that the SRID can be variable depending on the query the rows have one SRID or another so I don't want to set it to always being one.
Test database is created separately and does not contain the same data as the main application database. Try using pdb and listing all entries inside the parcelas table. Unless TestView means just a mock view for the time being.
Using pdb:
import pdb, pdb.set_trace()
Parcelas.objects.all()
In case the records geometry needs to be compared to a geojson like object one approach is to convert the object to GEOSGeometry and then find the record using .get(), .filter() etc.
For example, in case of an API JSON request payload that contains somewhere in the payload the following field:
"geometry": {
"type": "Polygon",
"coordinates": [
[
[21.870314, 39.390873],
[21.871913, 39.39319],
[21.874029, 39.392443],
[21.873401, 39.391328],
[21.873369, 39.391272],
[21.873314, 39.391171],
[21.872715, 39.390024],
[21.870314, 39.390873]
]
]
}
One can use the following code:
import json
from django.contrib.gis.geos import GEOSGeometry
# Assuming the python dictionary containing the geometry field is geometry_dict
payload_geometry = GEOSGeometry(json.dumps(geometry_dict))
parcel = Parcel.objects.get(geometry=payload_geometry)
I'm trying to fetch all the products from the firebase database, but in the json data form.
Here's the structure of my database:
products{
0{
name:...
price:...
}
1{
name:..
price:..
and so on. And below is the code I tried:
import json
from .models import Product
import pyrebase
def get_products():
database = firebase_key().database()
product_list = Product.objects.all()
r = database.child("products").get().each()
jsonList = r.json()
jsonData = jsonList['products']
data = []
for products in r:
productData = {}
productData['name'] = products.name
productData['image'] = products.image
productData['price'] = products.price
productData['description'] = products.description
data.append(productData)
return data
I'm new to both django and firebase, so any help would be appreciated
As #Kevin pointed out the each does not return a json, but a list. You can check it out on the pyrebase documentation.
Your code should probably look like this:
all_products = database.child("products").get()
for product in all_products.each():
data.append(product.val()) # This works if your fields have the same names.
Edit
If you still need data as a JSON.
json_data = json.dumps(data)
I have a form that accepts a list of strings :
class MyForm(Form):
__orders__ = None
order_by = FieldList(StringField('order_by'))
And here's my view :
#app.route("/")
def my_view():
form = MyForm(request.args)
print form.order_by.entries
I tried to request the url with :
/?order_by=hello&order_by=world
/?order_by[]=hello&order_by[]=world
/?order_by%5B%5D=hello&order_by%5B%5D=world
form.order_by.entries is always empty ([])
What am I missing ?
Ok here's how I did, using SelectMultipleField, but without having to deal with choices :
class MultipleTextField(SelectMultipleField):
"""
No different from a normal select field, except this one can take (and
validate) multiple choices. You'll need to specify the HTML `rows`
attribute to the select field when rendering.
"""
widget = widgets.Select(multiple=True)
coerce = str
choices = []
def pre_validate(self, form):
pass
I haven't tested this, but looking at the source code it seems this might work:
/?order_by-0=hello&order_by-1=world
I am trying to serialize the following view
def headerimage(request):
service_view = list( Service_images.objects.filter(service='7'))
return render_to_response ('headerimage.html',{'service_view':service_view}, context_instance=RequestContext(request))
This is supposed to return JSON in the form shown below
{"folderList":
["with schmurps"],
"fileList":
["toto006.jpg",
"toto012.jpg",
"toto013.jpg"
]
}
However, The folder list can be one or in this case will be "7" given that is the title("folder") of the images.
After taking into account the answer below, I came up with
def headerimage(request):
service_view = Service_images.objects.filter(service='7')
image = serializers.serialize("json", service_view)
mini = list(serializers.deserialize("json", image))
return HttpResponse(image, mimetype='application/javascript')
however, I am still looking for the simplest way to do this
service_view = Service_images.objects.filter(service='7').values('image')
The problem is that the django serializer expects whole models
Service_images.objects.filter() will return a QuerySet object for you, so basically wrapping this into list() makes no sense...
Look at the docs: http://docs.djangoproject.com/en/dev/topics/serialization/#id2, and use LazyEncoder definied there.
I usually follow the below way, when the json format requirement does not match with my model's representation.
from django.utils import simplejson as json
def headerimage(request):
service_view = Service_images.objects.filter(service='7')
ret_dict = {
"folderList":
[sv.image.folder for sv in service_view],
"fileList":
[sv.image.file for sv in service_view]
}
return (json.dumps(ret_dict), mimetype="application/json")