Display friends on map

This commit is contained in:
Gabriel Augendre 2019-03-02 12:47:44 +01:00
parent 02cb38219c
commit 940cb1e413
12 changed files with 234 additions and 5 deletions

View file

@ -16,6 +16,7 @@
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="leaflet" level="application" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Django" />

View file

@ -14,8 +14,9 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('map.urls')),
]

View file

@ -1,5 +1,15 @@
from django.contrib import admin
from django.contrib.admin import register
from django.contrib.auth.admin import UserAdmin
from .models import Friend
from .models import Friend, FriendLocation
admin.site.register(Friend, UserAdmin)
@register(FriendLocation)
class FriendLocationAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ('friend',)}),
('Place', {'fields': ('latitude', 'longitude')}),
('Dates', {'fields': ('start_date', 'end_date')}),
]

11
map/fields.py Normal file
View file

@ -0,0 +1,11 @@
from django.db import models
class CoordinateField(models.DecimalField):
def __init__(self, *args, **kwargs):
kwargs['max_digits'] = 11
kwargs['decimal_places'] = 8
kwargs['help_text'] = ('Format : xxx,xxxxxxxx<br>'
'(max 8 décimales, max 3 chiffres avant la virgule, séparateur : virgule)')
super().__init__(*args, **kwargs)

View file

@ -0,0 +1,29 @@
# Generated by Django 2.1.7 on 2019-03-02 11:13
from django.db import migrations, models
import map.fields
class Migration(migrations.Migration):
dependencies = [
('map', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='FriendLocation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('latitude', map.fields.CoordinateField(decimal_places=8, help_text='Format : xxx,xxxxxxxx<br>(max 8 décimales, max 3 chiffres avant la virgule, séparateur : virgule)', max_digits=11)),
('longitude', map.fields.CoordinateField(decimal_places=8, help_text='Format : xxx,xxxxxxxx<br>(max 8 décimales, max 3 chiffres avant la virgule, séparateur : virgule)', max_digits=11)),
('start_date', models.DateField(blank=True, null=True, verbose_name='from')),
('end_date', models.DateField(blank=True, null=True, verbose_name='until')),
],
options={
'abstract': False,
},
),
]

View file

@ -0,0 +1,21 @@
# Generated by Django 2.1.7 on 2019-03-02 11:17
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('map', '0002_friendlocation'),
]
operations = [
migrations.AddField(
model_name='friendlocation',
name='friend',
field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
preserve_default=False,
),
]

View file

@ -1,10 +1,36 @@
from django.contrib.auth.models import AbstractUser
from django.db import models
from map.fields import CoordinateField
class BaseModel(models.Model):
class Meta:
abstract = True
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Friend(AbstractUser):
pass
# class Location(models.Model):
# latitude = models.
class FriendLocation(BaseModel):
latitude = CoordinateField()
longitude = CoordinateField()
start_date = models.DateField('from', blank=True, null=True)
end_date = models.DateField('until', blank=True, null=True)
friend = models.ForeignKey(Friend, on_delete=models.CASCADE)
@property
def latitude_str(self):
return str(self.latitude)
@property
def longitude_str(self):
return str(self.longitude)
def __str__(self):
return f'{self.friend.get_full_name()} from {self.start_date} to {self.end_date}'

4
map/static/map/style.css Normal file
View file

@ -0,0 +1,4 @@
#map {
height: 70vh;
margin-top: 1rem;
}

View file

@ -0,0 +1,82 @@
{% load static %}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<!-- Fontawesome CSS -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css"
integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<link rel="stylesheet" href="{% static 'map/style.css' %}">
{% block add-head %}
{% endblock %}
<title>{{ app.site.name }} &centerdot; {% block title %}Home{% endblock %}</title>
</head>
<body>
{#{% include 'map/navbar.html' %}#}
<div class="container">
{% for message in messages %}
<div class="alert alert-dismissible alert-{{ message.tags }} fade show" role="alert">
{{ message|safe }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
{% endfor %}
<div class="row">
<div class="col-12">
<h1>{% block h1 %}{% endblock %}</h1>
</div>
</div>
{% block quick_actions %}
{% if quick_actions %}
<div class="row">
<div class="col-12 d-none d-md-block"> {# Visible only on large screens #}
{% for qa in quick_actions %}
<a href="{{ qa.url }}" class="btn btn-{{ qa.category }}">
{% if qa.icon %}<i class="{{ qa.icon }}"></i>{% endif %}
{{ qa.display }}
</a>
{% endfor %}
</div>
<div class="col-12 d-md-none"> {# Visible only on small screens #}
{% for qa in quick_actions %}
<a href="{{ qa.url }}" class="btn btn-{{ qa.category }} btn-block">
{% if qa.icon %}<i class="{{ qa.icon }}"></i>{% endif %}
{{ qa.display }}
</a>
{% endfor %}
</div>
</div>
{% endif %}
{% endblock %}
{% block content %}
{% endblock %}
</div>
<!-- Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
{% block js %}
{% endblock %}
</body>
</html>

View file

@ -0,0 +1,32 @@
{% extends 'map/base.html' %}
{% load static %}
{% block title %}Carte autour de {{ place }}{% endblock %}
{% block h1 %}Carte autour de {{ place }}{% endblock %}
{% block add-head %}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css"
integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
crossorigin=""/>
{% endblock %}
{% block content %}
<div id="map"></div>
{% endblock %}
{% block js %}
<script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"
integrity="sha512-QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg=="
crossorigin=""></script>
<script type="application/javascript">
let map = L.map('map').setView([45.805, 2.67], 5);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
{% for location in locations %}
let marker = L.marker([{{ location.latitude_str }}, {{ location.longitude_str }}]).addTo(map);
marker.bindPopup("<strong>{{ location.friend.get_full_name }}</strong> from {{ location.start_date }} until {{ location.end_date }}").openPopup();
{% endfor %}
</script>
{% endblock %}

6
map/urls.py Normal file
View file

@ -0,0 +1,6 @@
from django.urls import path
from map import views
urlpatterns = [
path('map/', views.MapView.as_view()),
]

View file

@ -1,3 +1,9 @@
from django.shortcuts import render
from django.views.generic import ListView
from map import models
# Create your views here.
class MapView(ListView):
model = models.FriendLocation
context_object_name = 'locations'
template_name = 'map/map.html'