나는 최근에이 요구 사항을 가지고 있었고 조금 옮겼다. 그러나 나는 나눌 것이라고 생각했다. (Django 2.0)
입력 된 좌표가 인 30 자 CharField를 만들었습니다.N 35º 44.265 W 41º 085.155
(나는 그게 어디에 있든 ...) 그리고 필드 값을 저장하기 위해 모델에 맞게 정렬되어 있습니다.
import re
from django.core.exceptions import ValidationError
COORDINATES_REGEX = r'(?:[NS])\s*([0-9]{2})[\º\°]?\s+([0-9]{1,3}\.[0-9]{3})\s*(?:[EW])\s*([0-9]{2,3})[\º\°]?\s+([0-9]{2,3}\.[0-9]{3})'
def decode_coords_string(str):
"""
Given a string, converts it to a decimal (lat, lng, 'OK', matched_string) tuple.
If invalid, returns "(None, None, <some reason>, None)."
Test for errors by checking that the coordinate is not 'None.'
'matched_string' returns the actual extent of the matched string regardless of where in the input-string it was,
for sanitizing the input when storing it in the database. (If the input string contains only blanks, we should
store an empty-string.)
The model will replace the field-value with this matched-string.
"""
# Dispose of empty input, returning an empty string(!) as the 'matched_string' in this case.
r = re.compile(r'^\s*$')
if r.match(str):
return (None, None, 'Empty string', '')
# Build the regex for coordinates.
r = re.compile(COORDINATES_REGEX, re.IGNORECASE)
# Try to match the string
p = r.match(str)
if p is None:
return (None, None, 'Syntax error', None)
# Get the pieces and expressly convert them to numeric types
(lat_degs, lat_mins, lng_degs, lng_mins) = p.groups()
lat_degs = int(lat_degs)
lat_mins = float(lat_mins)
lng_degs = int(lng_degs)
lng_mins = float(lng_mins)
# Throw out anything that simply does not make sense
if (lat_degs > 180) or (lng_degs > 180) or (lat_mins > 60.0) or (lng_mins > 60.0):
return (None, None, 'Degs/Mins value(s) out of bounds')
latitude = float(lat_degs) + (lat_mins/60.0)
longitude = (float(lng_degs) + (lng_mins/60.0)) * -1.0
return (latitude, longitude, 'OK', p.group())
def validate_coords(str):
"""
Simple validator for a coordinate string.
"""
(lat, lng, reason, str2) = decode_coords_string(str)
if lat is None:
raise ValidationError('Invalid coordinates: ' + reason)
입력 CharField
는도 심볼은 여러 가지 방법으로 지정되거나 완전히 생략 될 수 있음을주의
validators=[validate_coords]
도 지정한다.
admin.py
에서
def save(self, *args, **kwargs):
"""
Calculate and automatically populate the numeric lat/long figures.
This routine assumes that the string is either empty or that it has been validated.
An empty string – or, for that matter, an invalid one – will be (None, None).
"""
(lat, lng, reason, cleaned) = decode_coords_string(self.coordinate_str)
self.coordinate_str = cleaned
self.latitude = lat
self.longitude = lng
super().save(*args, **kwargs)
는 I는 사용자 혼란을 방지하는 관점에서 latitude
및 longitude
필드 (플로트 필드이다 둘) 제외 :
하고 모델은 다음과 같은 간단한 방법을 포함한다. 숫자 필드는 자동으로 계산되지만 표시되지는 않습니다.
매우 간단하지만 구현하기 쉽고 간단합니다. 그것을 생각하지 않았습니다 - 감사합니다! –