Usage

Model Layer

You need to add three model fields to your model:

  1. OSMField
  2. LatitudeField
  3. LongitudeField

django-osm-field expects them to have a certain name schema: The OSMField defines the base name, the LatitudeField and LongitudeField have the same name appended with _lat and _lon respectively. See the following example to get an idea:

from django.db import models

from osm_field.fields import LatitudeField, LongitudeField, OSMField


class MyModel(models.Model):
    location = OSMField()
    location_lat = LatitudeField()
    location_lon = LongitudeField()

It is possible, though, to overwrite the default naming for latitude and longitude fields by giving their names as arguments to the OSMField:

class MyModel(models.Model):
    location = OSMField(lat_field='latitude', lon_field='longitude')
    latitude = LatitudeField()
    longitude = LongitudeField()

Form Layer

from django import forms

from .models import MyModel


class MyModelForm(forms.ModelForm):

    class Meta:
        fields = ('location', 'location_lat', 'location_lon', )
        model = MyModel

Formset Layer

To use OSMField with formsets with Django < 1.9, you must mixin the OSMFormMixin to your child form class:

models.py:

from django.db import models

from osm_field.fields import LatitudeField, LongitudeField, OSMField


class ParentModel(models.Model):
    name = models.CharField(max_length=31)


class ChildModel(models.Model):
    parent = models.ForeignKey(ParentModel, related_name='children')
    location = OSMField()
    location_lat = LatitudeField()
    location_lon = LongitudeField()

forms.py:

from django import forms

from osm_field.forms import OSMFormMixin

from .models import ChildModel, ParentModel


class ChildModelInlineForm(OSMFormMixin, forms.ModelForm):
    class Meta:
        fields = ('location', 'location_lat', 'location_lon', )
        model = ChildModel

ChildModelFormset = forms.models.inlineformset_factory(
    ParentModel, ChildModel, form=ChildModelInlineForm
)

Note that you ONLY need to do this for Django < 1.9, but this will still work without modification (but is unnecessary) for Django >= 1.9.

View Layer

from django.views.generic import CreateView

from .forms import MyModelForm
from .models import MyModel


class MyCreateView(CreateView):
    form_class = MyModelForm
    model = MyModel

Template Layer

django-osm-field shipps with a minimized jQuery version. To access it in a template use the static templatetag from the staticfiles Django app:

<script type="text/javascript" src="{% static "js/vendor/jquery-2.1.0.min.js" %}"></script>

You can of course load jQuery from a CDN as well:

<script type="text/javascript" src="//code.jquery.com/jquery-2.1.0.min.js"></script>

To get the front-end to work, you also need to include some CSS and JavaScript files. You can do this by simply using {{ form.media }} or by adding those lines explicitly:

<link href="{% static "css/vendor/leaflet.css" %}" type="text/css" media="screen" rel="stylesheet" />
<link href="{% static "css/osm_field.css" %}" type="text/css" media="screen" rel="stylesheet" />
<script type="text/javascript" src="{% static "js/vendor/leaflet.js" %}"></script>
<script type="text/javascript" src="{% static "js/osm_field.js" %}"></script>

In the end your template should look similar to this:

{% load static from staticfiles %}<!DOCTYPE HTML>
<html>
  <head>
    <title></title>
    <link rel="stylesheet" href="{% static "css/example.css" %}">
    <!-- Either serve jQuery yourself -->
    <script type="text/javascript" src="{% static "js/vendor/jquery-2.1.0.min.js" %}"></script>
    <!-- or from a CDN -->
    <script type="text/javascript" src="//code.jquery.com/jquery-2.1.0.min.js"></script>
  </head>
  <body>
    {{ form.media }}
    <form action="" method="post">
      {% csrf_token %}
      {{ form.as_p }}
      <input type="submit" value="Save" />
    </form>
  </body>
</html>