Gibt es ein Widget für PointField als separate Längen-/Breiteneingaben? Wie SplitDateTimeWidget für DateTimeField.Breiten-/Längengrad-Widget für Punktfeld?
Antwort
Hier ist mein Arbeits benutzerdefiniertes Feld und widget:
class LatLongWidget(forms.MultiWidget):
"""
A Widget that splits Point input into two latitude/longitude boxes.
"""
def __init__(self, attrs=None, date_format=None, time_format=None):
widgets = (forms.TextInput(attrs=attrs),
forms.TextInput(attrs=attrs))
super(LatLongWidget, self).__init__(widgets, attrs)
def decompress(self, value):
if value:
return tuple(reversed(value.coords))
return (None, None)
class LatLongField(forms.MultiValueField):
widget = LatLongWidget
srid = 4326
default_error_messages = {
'invalid_latitude' : _('Enter a valid latitude.'),
'invalid_longitude' : _('Enter a valid longitude.'),
}
def __init__(self, *args, **kwargs):
fields = (forms.FloatField(min_value=-90, max_value=90),
forms.FloatField(min_value=-180, max_value=180))
super(LatLongField, self).__init__(fields, *args, **kwargs)
def compress(self, data_list):
if data_list:
# Raise a validation error if latitude or longitude is empty
# (possible if LatLongField has required=False).
if data_list[0] in validators.EMPTY_VALUES:
raise forms.ValidationError(self.error_messages['invalid_latitude'])
if data_list[1] in validators.EMPTY_VALUES:
raise forms.ValidationError(self.error_messages['invalid_longitude'])
# SRID=4326;POINT(1.12345789 1.123456789)
srid_str = 'SRID=%d'%self.srid
point_str = 'POINT(%f %f)'%tuple(reversed(data_list))
return ';'.join([srid_str, point_str])
return None
Erstellen Sie ein benutzerdefiniertes Widget für diese, können Sie sich von SelectDateWidget
here inspirieren lassen.
@Ramast, nähern sich das gleiche Problem in einer pythonic Weise. Ich habe die Änderungen in meinen Code aufgenommen, es fühlt sich toll an, immer besser zu werden.
Dies ist, wie ich es geschafft, -bei letzt lattitude und Länge getrennte Felder zu halten, ohne sie in der Datenbank zu speichern, die, da die Werte bereits im PointField gespeichert werden.
Die Idee ist:
- Wenn wir einen neuen Eintrag einfügen, die Breiten- und Längenfelder verwendet werden, um die PointField
- einstellen Wenn wir einen vorhandenen PointField Eintrag öffnen, wird es verwendet werden Geben Sie die Breiten- und Längengradwerte in den entsprechenden FormFields an.
models.py
from django.contrib.gis.db import models as geomodels
class Entry(geomodels.Model):
point = geomodels.PointField(
srid=4326,
blank=True,
)
admin.py
from myapp.forms import EntryForm
from django.contrib import admin
class EntryAdmin(admin.ModelAdmin):
form = EntryForm
admin.site.register(Entry, EntryAdmin)
forms.py
from django import forms
from myapp.models import Entry
from django.contrib.gis.geos import Point
class MarketEntryForm(forms.ModelForm):
latitude = forms.FloatField(
min_value=-90,
max_value=90,
required=True,
)
longitude = forms.FloatField(
min_value=-180,
max_value=180,
required=True,
)
class Meta(object):
model = MarketEntry
exclude = []
widgets = {'point': forms.HiddenInput()}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
coordinates = self.initial.get('point', None)
if isinstance(coordinates, Point):
self.initial['latitude'], self.initial['longitude'] = coordinates.tuple
def clean(self):
data = super().clean()
latitude = data.get('latitude')
longitude = data.get('longitude')
point = data.get('point')
if latitude and longitude and not point:
data['point'] = Point(longitude, latitude)
return data
Dieses basiert auf @ rara_tiru-Lösung, aber mit einigen Verbesserungen
class GisForm(forms.ModelForm):
"""
This form can be used by any model that has "coordinates" field.
It will show a better looking map than the default one
"""
lat = forms.FloatField(required=False)
lng = forms.FloatField(required=False)
coordinates = PointField(widget=CustomPointWidget(), required=False, srid=4326)
def __init__(self, *args, **kwargs):
super(GisForm, self).__init__(*args, **kwargs)
coordinates = self.initial.get("coordinates", None)
if isinstance(coordinates, Point):
self.initial["lng"], self.initial["lat"] = coordinates.tuple
def clean(self):
data = super(GisForm, self).clean()
if "lat" in self.changed_data or "lng" in self.changed_data:
lat, lng = data.pop("lat", None), data.pop("lng", None)
data["coordinates"] = Point(lng, lat, srid=4326)
if not (data.get("coordinates") or data.get("lat")):
raise forms.ValidationError({"coordinates": "Coordinates is required"})
return data
Damit können Benutzer entweder den Standort auf der Karte festlegen oder die Werte für lat/lng manuell eingeben. einmal gespeichert wird die Karte die specificed lat/lng Wert
Die Antworten sind für den Aufbau Ihrer eigenen Lösung widerspiegeln, aber wenn Sie eine einfache Lösung wollen, die gut aussieht und ist einfach zu bedienen, versuchen: http://django-map-widgets.readthedocs.io/en/latest/index.html
Sie können:
- geben Sie die Koordinaten
- Navigation direkt auf der Karte
- Artikel nachschlagen von Google Orten.
- 1. Wie bekomme ich den nächsten Punkt zu einem Punkt in einem Punktfeld?
- 2. Ordnen Sie ein PostGIS Geometrie Punktfeld mit Hibernate auf Spring Boot
- 3. Scala für() vs für {}
- 4. Wie wird ein Django PointField-Modellattribut zugewiesen?
- 5. Verbindungszeichenfolge für Informix für .NET
- 6. Mindestanforderungen für Unity für Android?
- 7. Gruppe für Monat für Anwesenheitsliste
- 8. Modul für OneSignal für Appcelerator
- 9. Vorschlag für Vorlagenbuch für C++?
- 10. Alternative für BtsMSITask für BizTalk
- 11. Elmah für WCF für Ausnahmebehandlung
- 12. Beispiel für den Domain-Namen für mailgun be für nodejs?
- 13. Einstellung für Ländereinstellung für Java-Überschreibung für bestimmtes Gebietsschema
- 14. Implementieren von Bedingungsvariablen für CRITICAL_SECTIONs für WinThreads für XP
- 15. Alternative für ‚in‘ Operator für verschachtelte Listen
- 16. Validierung für TextBox für ein Benutzerformular
- 17. Jeder Ersatz für Bugsense für ACRA
- 18. "für" Schleife in einem anderen "für" Schleife
- 19. Empfehlung für Bildschirm-Video-Capture für Demos
- 20. istream für die Kommandozeileneingabe für C++/Poco
- 21. Zeitbedingung für Überprüfer für GCM Zweck
- 22. Swift: Verschlüsselte Eingabe für UITextField für Kartendetails
- 23. Relativer Pfad für Asset-Funktion für Laravel
- 24. Chrome für iOS: „Immer erlauben“ für Plätzchen
- 25. Spline-Interpolation für Werte für die Zeit
- 26. Beispiel für Akka EventBus für Java
- 27. Syntax für reguläre Ausdrücke für "Nichts anpassen"?
- 28. Admob Unterstützung für Kivy (Python für Android)
- 29. Sitzungsbehandlung für in WCF für ASP.net-Client
- 30. Pfad für die Installation Binärdateien für Kabale
Ich erhalte eine ‚ungültige Geometriewert‘ Fehler, wenn ich diese – fangsterr
verwenden @fangsterr Sie verwenden '' 'FloatField''' oder' '' DecimalField''' Ihre Koordinaten und Überschreibung zu speichern die Speichermethode zum Aktualisieren des '' 'PointField''', wie hier [hier] (http://stackoverflow.com/a/22309195/2996101) – raratiru