port to new django, AI automated

This commit is contained in:
2026-03-30 22:35:36 +02:00
parent e2d166e437
commit 372da3caa9
215 changed files with 9283 additions and 2981 deletions

View File

@@ -1,26 +1,23 @@
from django.forms import fields
from location_field.widgets import LocationWidget
from .widgets import LocationWidget
class PlainLocationField(fields.CharField):
"""A form field for entering location data with a map widget."""
def __init__(self, based_field=None, zoom=None, default=None, *args, **kwargs):
kwargs['initial'] = default
kwargs["initial"] = default
self.widget = LocationWidget(based_field=based_field, zoom=zoom, **kwargs)
dwargs = {
'required': True,
'label': None,
'initial': None,
'help_text': None,
'error_messages': None,
'show_hidden_initial': False,
# Extract only the valid kwargs for CharField
field_kwargs = {
"required": kwargs.get("required", True),
"label": kwargs.get("label", None),
"initial": kwargs.get("initial", None),
"help_text": kwargs.get("help_text", None),
"error_messages": kwargs.get("error_messages", None),
"show_hidden_initial": kwargs.get("show_hidden_initial", False),
}
for attr in dwargs:
if attr in kwargs:
dwargs[attr] = kwargs[attr]
super(PlainLocationField, self).__init__(*args, **dwargs)
super().__init__(*args, **field_kwargs)

View File

@@ -40,14 +40,14 @@
theObject.placeMarker( l );
theObject.saveToInputField();
});
};
}
this.placeMarker = function( location )
{
this.marker.setPosition( location );
this.map.setCenter( location );
this.map.panTo( location );
};
}
this.geocode = function(address, cb)
@@ -60,7 +60,7 @@
}
});
}
};
}
this.geocode_reverse = function( cb)
{
@@ -71,13 +71,13 @@
}
});
}
};
}
this.saveToInputField = function()
{
var p = this.marker.getPosition();
coordinate_field.value = p.lat().toFixed(6) + "," + p.lng().toFixed(6) + "," + this.map.getZoom() ;
};
}
this.loadFromInputField = function()
{
@@ -95,7 +95,7 @@
this.placeMarker( init_position );
this.map.setZoom( 16 );
}
};
}
// --------------------------- Constructor -------------------------------------
@@ -118,7 +118,7 @@
});
theObject.loadFromInputField();
};
}
this.init();
}
@@ -132,6 +132,7 @@
autoOpen: false
} );
$('input[data-location-widget]').click( function() {
var formCoordField = $(this);
@@ -168,7 +169,7 @@
$dialogElement[0].map.placeMarkerUsingAddressString( $dialogLocationField.val() );
$dialogLocationField.on("keypress", function(e) {
if ( e.keyCode === 13 ) { // enter
if ( e.keyCode == 13 ) { // enter
$dialogElement[0].map.placeMarkerUsingAddressString( $dialogLocationField.val() );
return false;
}
@@ -183,5 +184,7 @@
$dialogElement.dialog('open');
});
});

View File

@@ -3,7 +3,9 @@ from django.db.models import CharField
from location_field import forms
class BaseLocationField(object):
class BaseLocationField:
"""Base class for location fields."""
def __init__(self, based_field=None, zoom=2, default=None, *args, **kwargs):
self._based_field = based_field
self._zoom = zoom
@@ -11,29 +13,31 @@ class BaseLocationField(object):
self.default = default
def formfield(self, **kwargs):
return super(BaseLocationField, self).formfield(
return super().formfield(
form_class=self.formfield_class,
based_field=self._based_field,
zoom=self._zoom,
default=self._default,
**kwargs)
**kwargs,
)
class PlainLocationField(BaseLocationField, CharField):
"""A CharField that stores location data as 'latitude,longitude,zoom'."""
formfield_class = forms.PlainLocationField
def __init__(self, based_field=None, zoom=None,
max_length=63, *args, **kwargs):
super(PlainLocationField, self).__init__(based_field=based_field,
zoom=zoom, *args, **kwargs)
def __init__(self, based_field=None, zoom=None, max_length=63, *args, **kwargs):
BaseLocationField.__init__(
self, based_field=based_field, zoom=zoom, *args, **kwargs
)
CharField.__init__(self, max_length=max_length, *args, **kwargs)
# south compatibility
try:
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^location_field\.models\.PlainLocationField"])
except:
pass
def deconstruct(self):
"""Return enough information to recreate the field."""
name, path, args, kwargs = super().deconstruct()
if self._based_field is not None:
kwargs["based_field"] = self._based_field
if self._zoom is not None:
kwargs["zoom"] = self._zoom
return name, path, args, kwargs

View File

@@ -1,9 +1,8 @@
import os
from django.urls import re_path
from django.views.static import serve
from django.urls import path
app_dir = os.path.dirname(__file__)
app_name = "location_field"
urlpatterns = [
re_path(r'^media/(.*)$', serve, {'document_root': '%s/media' % app_dir}),
]
# Static files for location_field should be placed in location_field/static/location_field/
# and will be served automatically by Django's staticfiles system.
urlpatterns = []

View File

@@ -1,54 +1,67 @@
import os
from django.forms import widgets
from django.utils.safestring import mark_safe
from django.conf import settings
import os
class LocationWidget(widgets.TextInput):
def __init__(self, attrs=None, based_field=None, zoom=None, width=610, height=480, **kwargs):
"""A widget that displays a map for selecting a location."""
def __init__(
self, attrs=None, based_field=None, zoom=None, width=610, height=480, **kwargs
):
self.based_field = based_field
self.zoom = zoom
self.width = width
self.height = height
super(LocationWidget, self).__init__(attrs)
super().__init__(attrs)
def render(self, name, value, attrs=None, renderer=None):
if value is not None and len(value) > 0:
lat, lng, zoom = value.split(',')
value = '%s,%s,%d' % (
float(lat),
float(lng),
float(zoom)
)
try:
lat, lng, zoom = value.split(",")
value = "%s,%s,%d" % (float(lat), float(lng), int(float(zoom)))
except (ValueError, TypeError):
value = ""
else:
value = ''
value = ""
based_field = "#id_" + self.based_field.name
if self.based_field is not None:
based_field = "#id_" + self.based_field.name
else:
based_field = ""
attrs = attrs or {}
attrs['readonly'] = "readonly"
attrs['data-location-widget'] = name
attrs['data-based-field'] = based_field
attrs['data-zoom'] = self.zoom
attrs['data-map'] = '#map_' + name
attrs['data-dialog-id'] = "#map_dialog_" + name
text_input = super(LocationWidget, self).render(name, value, attrs)
attrs["readonly"] = "readonly"
attrs["data-location-widget"] = name
attrs["data-based-field"] = based_field
attrs["data-zoom"] = self.zoom or 7
attrs["data-map"] = "#map_" + name
attrs["data-dialog-id"] = "#map_dialog_" + name
text_input = super().render(name, value, attrs, renderer)
# Load the HTML template for the map dialog
path = os.path.abspath(os.path.dirname(__file__))
with open(path + "/media/form.html", 'r') as content_file:
html = content_file.read()
template_path = os.path.join(path, "media", "form.html")
return mark_safe(text_input + html % {'name': name, 'width': self.width, 'height': self.height})
try:
with open(template_path, "r") as content_file:
html = content_file.read()
html = html % {"name": name, "width": self.width, "height": self.height}
except (FileNotFoundError, IOError):
html = ""
return mark_safe(text_input + html)
class Media:
css = {
'all': ('/location_field/media/form.css',)
}
# Use schemaless URL so it works with both, http and https websites
css = {"all": ("location_field/form.css",)}
js = (
'//maps.google.com/maps/api/js?sensor=false&language=de&key={}'.format(settings.GOOGLE_MAPS_API_KEY),
'/static/js/bindWithDelay.js',
'/location_field/media/form.js',
# jQuery and jQuery UI (consider using local copies or newer CDN)
"https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js",
"https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js",
# Google Maps API - you may need to add an API key
"https://maps.google.com/maps/api/js?language=de",
"js/bindWithDelay.js",
"location_field/form.js",
)