[FEAT] Update dependencies

Upgrade versions of most packages and make other required changes to ensure compatibility. Update database models and migrations to match new requirements set by Django
This commit is contained in:
2023-01-05 17:49:27 +00:00
parent 770b4f1114
commit 7e2491be76
24 changed files with 293 additions and 84 deletions

2
Dockerfile Normal file → Executable file
View File

@@ -1,4 +1,4 @@
FROM python:3.8-slim FROM python:3.9-slim
RUN groupadd -r mapper && useradd --no-log-init -r -g mapper mapper RUN groupadd -r mapper && useradd --no-log-init -r -g mapper mapper

View File

@@ -0,0 +1,33 @@
# Generated by Django 4.1.4 on 2023-01-05 16:57
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('activities', '0006_activity_attendance_optional'),
]
operations = [
migrations.AlterField(
model_name='activity',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='activitymedium',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='activityseries',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='activitytype',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
]

View File

@@ -165,7 +165,6 @@ THIRD_PARTY_APPS = [
'post_office', 'post_office',
'bootstrap_datepicker_plus', 'bootstrap_datepicker_plus',
'hijack', 'hijack',
'compat',
] ]
FIRST_PARTY_APPS = [ FIRST_PARTY_APPS = [
@@ -184,6 +183,7 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'hijack.middleware.HijackUserMiddleware',
] ]
ROOT_URLCONF = 'breccia_mapper.urls' ROOT_URLCONF = 'breccia_mapper.urls'
@@ -417,6 +417,18 @@ else:
default=(EMAIL_PORT == 465), default=(EMAIL_PORT == 465),
cast=bool) cast=bool)
# Bootstrap Datepicker Plus Settings
BOOTSTRAP_DATEPICKER_PLUS = {
"variant_options": {
"date": {
"format": "%Y-%m-%d",
},
}
}
# Database default automatic primary key
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# Upstream API keys # Upstream API keys
GOOGLE_MAPS_API_KEY = config('GOOGLE_MAPS_API_KEY', default=None) GOOGLE_MAPS_API_KEY = config('GOOGLE_MAPS_API_KEY', default=None)

52
breccia_mapper/templates/base.html Normal file → Executable file
View File

@@ -16,21 +16,23 @@
{% bootstrap_css %} {% bootstrap_css %}
<link rel="stylesheet" <link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/fontawesome.min.css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/fontawesome.min.css"
integrity="sha256-/sdxenK1NDowSNuphgwjv8wSosSNZB0t5koXqd7XqOI=" integrity="sha512-giQeaPns4lQTBMRpOOHsYnGw1tGVzbAIHUyHRgn7+6FmiEgGGjaG0T2LZJmAPMzRCl+Cug0ItQ2xDZpTmEc+CQ=="
crossorigin="anonymous" /> crossorigin="anonymous"
referrerpolicy="no-referrer" />
<link rel="stylesheet" <link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/solid.min.css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/solid.min.css"
integrity="sha256-8DcgqUGhWHHsTLj1qcGr0OuPbKkN1RwDjIbZ6DKh/RA=" integrity="sha512-6mc0R607di/biCutMUtU9K7NtNewiGQzrvWX4bWTeqmljZdJrwYvKJtnhgR+Ryvj+NRJ8+NnnCM/biGqMe/iRA=="
crossorigin="anonymous" /> crossorigin="anonymous"
referrerpolicy="no-referrer" />
{% load staticfiles %} {% load static %}
<link rel="stylesheet" href="{% static 'css/global.css' %}"> <link rel="stylesheet" href="{% static 'css/global.css' %}">
<link rel="stylesheet" <link rel="stylesheet"
type="text/css" type="text/css"
href="{% static 'hijack/hijack-styles.css' %}" /> href="{% static 'hijack/hijack.min.css' %}" />
{% if 'javascript_in_head'|bootstrap_setting %} {% if 'javascript_in_head'|bootstrap_setting %}
{% if 'include_jquery'|bootstrap_setting %} {% if 'include_jquery'|bootstrap_setting %}
@@ -107,13 +109,13 @@
<li class="nav-item"> <li class="nav-item">
{% if request.user.person %} {% if request.user.person %}
<a href="{% url 'people:person.profile' %}" class="nav-link"> <a href="{% url 'people:person.profile' %}" class="nav-link">
<i class="fas fa-user-circle"></i> <i class="fa-solid fa-circle-user"></i>
{{ request.user }} {{ request.user }}
</a> </a>
{% else %} {% else %}
<a href="{% url 'people:person.create' %}?user" class="nav-link"> <a href="{% url 'people:person.create' %}?user" class="nav-link">
<i class="fas fa-user-circle"></i> <i class="fa-solid fa-circle-user"></i>
{{ request.user }} {{ request.user }}
</a> </a>
@@ -122,7 +124,7 @@
<li class="nav-item"> <li class="nav-item">
<a href="{% url 'logout' %}" class="nav-link"> <a href="{% url 'logout' %}" class="nav-link">
<i class="fas fa-sign-out-alt"></i> <i class="fa-solid fa-right-from-bracket"></i>
Log Out Log Out
</a> </a>
</li> </li>
@@ -130,7 +132,7 @@
{% else %} {% else %}
<li class="nav-item"> <li class="nav-item">
<a href="{% url 'login' %}" class="nav-link"> <a href="{% url 'login' %}" class="nav-link">
<i class="fas fa-sign-in-alt"></i> <i class="fa-solid fa-right-to-bracket"></i>
Log In Log In
</a> </a>
</li> </li>
@@ -149,8 +151,30 @@
</div> </div>
{% endif %} {% endif %}
{% load hijack_tags %} {% load hijack %}
{% hijack_notification %}
{# Hijack notification if user is hijacked #}
{% if person.user == request.user and request.user.is_hijacked %}
<div class="djhj" id="djhj">
<div class="djhj-notification">
<div class="djhj-message">
{% blocktrans trimmed with user=request.user %}
You are currently working on behalf of <em>{{ user }}</em>.
{% endblocktrans %}
</div>
<form action="{% url 'hijack:release' %}" method="POST" class="djhj-actions">
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<button class="djhj-button" onclick="document.getElementById('djhj').style.display = 'none';" type="button">
{% trans 'hide' %}
</button>
<button class="djhj-button" type="submit">
{% trans 'release' %}
</button>
</form>
</div>
</div>
{% endif %}
{% if request.user.is_authenticated and not request.user.has_person %} {% if request.user.is_authenticated and not request.user.has_person %}
<div class="alert alert-info rounded-0" role="alert"> <div class="alert alert-info rounded-0" role="alert">

View File

@@ -1,7 +1,7 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block extra_head %} {% block extra_head %}
{% load staticfiles %} {% load static %}
<link rel="stylesheet" <link rel="stylesheet"
href="{% static 'css/masthead.css' %}"> href="{% static 'css/masthead.css' %}">
{% endblock %} {% endblock %}
@@ -33,7 +33,7 @@
<div class="card-body"> <div class="card-body">
<h2 class="card-title">Do Feature 1</h2> <h2 class="card-title">Do Feature 1</h2>
<span class="fas fa-5x fa-atlas"></span> <span class="fa-solid fa-5x fa-book-atlas"></span>
</div> </div>
</div> </div>
</div> </div>
@@ -43,7 +43,7 @@
<div class="card-body"> <div class="card-body">
<h2 class="card-title">Do Feature 2</h2> <h2 class="card-title">Do Feature 2</h2>
<span class="fas fa-5x fa-atlas"></span> <span class="fa-solid fa-5x fa-book-atlas"></span>
</div> </div>
</div> </div>
</div> </div>
@@ -53,7 +53,7 @@
<div class="card-body"> <div class="card-body">
<h2 class="card-title">Do Feature 3</h2> <h2 class="card-title">Do Feature 3</h2>
<span class="fas fa-5x fa-atlas"></span> <span class="fa-solid fa-5x fa-book-atlas"></span>
</div> </div>
</div> </div>
</div> </div>

8
people/forms.py Normal file → Executable file
View File

@@ -5,7 +5,7 @@ import typing
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from bootstrap_datepicker_plus import DatePickerInput from bootstrap_datepicker_plus.widgets import DatePickerInput
from django_select2.forms import ModelSelect2Widget, Select2Widget, Select2MultipleWidget from django_select2.forms import ModelSelect2Widget, Select2Widget, Select2MultipleWidget
from . import models from . import models
@@ -185,8 +185,8 @@ class PersonAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
widgets = { widgets = {
'nationality': Select2MultipleWidget(), 'nationality': Select2MultipleWidget(),
'country_of_residence': Select2Widget(), 'country_of_residence': Select2Widget(),
'organisation_started_date': DatePickerInput(format='%Y-%m-%d'), 'organisation_started_date': DatePickerInput(),
'project_started_date': DatePickerInput(format='%Y-%m-%d'), 'project_started_date': DatePickerInput(),
'latitude': forms.HiddenInput, 'latitude': forms.HiddenInput,
'longitude': forms.HiddenInput, 'longitude': forms.HiddenInput,
} }
@@ -325,7 +325,7 @@ class OrganisationRelationshipAnswerSetForm(forms.ModelForm,
class DateForm(forms.Form): class DateForm(forms.Form):
date = forms.DateField( date = forms.DateField(
required=False, required=False,
widget=DatePickerInput(format='%Y-%m-%d'), widget=DatePickerInput(),
help_text='Show relationships as they were on this date' help_text='Show relationships as they were on this date'
) )

4
people/migrations/0002_add_relationship_models.py Normal file → Executable file
View File

@@ -50,10 +50,10 @@ class Migration(migrations.Migration):
), ),
migrations.AddConstraint( migrations.AddConstraint(
model_name='relationshipquestionchoice', model_name='relationshipquestionchoice',
constraint=models.UniqueConstraint(fields=('question', 'text'), name='unique_question_answer'), constraint=models.UniqueConstraint(fields=('question', 'text'), name='unique_question_answer_relationshipquestionchoice'),
), ),
migrations.AddConstraint( migrations.AddConstraint(
model_name='relationship', model_name='relationship',
constraint=models.UniqueConstraint(fields=('source', 'target'), name='unique_relationship'), constraint=models.UniqueConstraint(fields=('source', 'target'), name='unique_relationship_relationship'),
), ),
] ]

2
people/migrations/0022_refactor_person_questions.py Normal file → Executable file
View File

@@ -50,6 +50,6 @@ class Migration(migrations.Migration):
), ),
migrations.AddConstraint( migrations.AddConstraint(
model_name='personquestionchoice', model_name='personquestionchoice',
constraint=models.UniqueConstraint(fields=('question', 'text'), name='unique_question_answer'), constraint=models.UniqueConstraint(fields=('question', 'text'), name='unique_question_answer_personquestionchoice'),
), ),
] ]

2
people/migrations/0035_add_organisation_questions.py Normal file → Executable file
View File

@@ -56,6 +56,6 @@ class Migration(migrations.Migration):
), ),
migrations.AddConstraint( migrations.AddConstraint(
model_name='organisationquestionchoice', model_name='organisationquestionchoice',
constraint=models.UniqueConstraint(fields=('question', 'text'), name='unique_question_answer'), constraint=models.UniqueConstraint(fields=('question', 'text'), name='unique_question_answer_organisationquestionchoice'),
), ),
] ]

View File

@@ -67,10 +67,10 @@ class Migration(migrations.Migration):
), ),
migrations.AddConstraint( migrations.AddConstraint(
model_name='organisationrelationshipquestionchoice', model_name='organisationrelationshipquestionchoice',
constraint=models.UniqueConstraint(fields=('question', 'text'), name='unique_question_answer'), constraint=models.UniqueConstraint(fields=('question', 'text'), name='unique_question_answer_organisationrelationshipquestionchoice'),
), ),
migrations.AddConstraint( migrations.AddConstraint(
model_name='organisationrelationship', model_name='organisationrelationship',
constraint=models.UniqueConstraint(fields=('source', 'target'), name='unique_relationship'), constraint=models.UniqueConstraint(fields=('source', 'target'), name='unique_relationship_organisationrelationship'),
), ),
] ]

View File

@@ -0,0 +1,119 @@
# Generated by Django 4.1.4 on 2023-01-05 16:57
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('people', '0054_add_option_for_auto_negative_response'),
]
operations = [
migrations.RemoveConstraint(
model_name='organisationrelationship',
name='unique_relationship_organisationrelationship',
),
migrations.RemoveConstraint(
model_name='relationship',
name='unique_relationship_relationship',
),
migrations.AlterField(
model_name='organisation',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='organisationanswerset',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='organisationquestion',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='organisationquestionchoice',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='organisationrelationship',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='organisationrelationshipanswerset',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='organisationrelationshipquestion',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='organisationrelationshipquestionchoice',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='person',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='personanswerset',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='personquestion',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='personquestionchoice',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='relationship',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='relationshipanswerset',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='relationshipquestion',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='relationshipquestionchoice',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='user',
name='first_name',
field=models.CharField(blank=True, max_length=150, verbose_name='first name'),
),
migrations.AlterField(
model_name='user',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AddConstraint(
model_name='organisationrelationship',
constraint=models.UniqueConstraint(fields=('source', 'target'), name='unique_relationship_modelorganisationrelationship'),
),
migrations.AddConstraint(
model_name='relationship',
constraint=models.UniqueConstraint(fields=('source', 'target'), name='unique_relationship_modelrelationship'),
),
]

5
people/models/organisation.py Normal file → Executable file
View File

@@ -35,6 +35,11 @@ class OrganisationQuestionChoice(QuestionChoice):
on_delete=models.CASCADE, on_delete=models.CASCADE,
blank=False, blank=False,
null=False) null=False)
class Meta(QuestionChoice.Meta):
constraints = [
models.UniqueConstraint(fields=['question', 'text'],
name='unique_question_answer_organisationquestionchoice')
]
class Organisation(models.Model): class Organisation(models.Model):

5
people/models/person.py Normal file → Executable file
View File

@@ -77,6 +77,11 @@ class PersonQuestionChoice(QuestionChoice):
on_delete=models.CASCADE, on_delete=models.CASCADE,
blank=False, blank=False,
null=False) null=False)
class Meta(QuestionChoice.Meta):
constraints = [
models.UniqueConstraint(fields=['question', 'text'],
name='unique_question_answer_personquestionchoice')
]
class Person(models.Model): class Person(models.Model):

2
people/models/question.py Normal file → Executable file
View File

@@ -92,7 +92,7 @@ class QuestionChoice(models.Model):
abstract = True abstract = True
constraints = [ constraints = [
models.UniqueConstraint(fields=['question', 'text'], models.UniqueConstraint(fields=['question', 'text'],
name='unique_question_answer') name='unique_question_answer_modelquestionchoice')
] ]
ordering = [ ordering = [
'question__order', 'question__order',

14
people/models/relationship.py Normal file → Executable file
View File

@@ -33,6 +33,11 @@ class RelationshipQuestionChoice(QuestionChoice):
on_delete=models.CASCADE, on_delete=models.CASCADE,
blank=False, blank=False,
null=False) null=False)
class Meta(QuestionChoice.Meta):
constraints = [
models.UniqueConstraint(fields=['question', 'text'],
name='unique_question_answer_relationshipquestionchoice')
]
class Relationship(models.Model): class Relationship(models.Model):
@@ -40,7 +45,7 @@ class Relationship(models.Model):
class Meta: class Meta:
constraints = [ constraints = [
models.UniqueConstraint(fields=['source', 'target'], models.UniqueConstraint(fields=['source', 'target'],
name='unique_relationship'), name='unique_relationship_modelrelationship'),
] ]
#: Person reporting the relationship #: Person reporting the relationship
@@ -122,6 +127,11 @@ class OrganisationRelationshipQuestionChoice(QuestionChoice):
on_delete=models.CASCADE, on_delete=models.CASCADE,
blank=False, blank=False,
null=False) null=False)
class Meta(QuestionChoice.Meta):
constraints = [
models.UniqueConstraint(fields=['question', 'text'],
name='unique_question_answer_organisationrelationshipquestionchoice')
]
class OrganisationRelationship(models.Model): class OrganisationRelationship(models.Model):
@@ -129,7 +139,7 @@ class OrganisationRelationship(models.Model):
class Meta: class Meta:
constraints = [ constraints = [
models.UniqueConstraint(fields=['source', 'target'], models.UniqueConstraint(fields=['source', 'target'],
name='unique_relationship'), name='unique_relationship_modelorganisationrelationship'),
] ]
#: Person reporting the relationship #: Person reporting the relationship

2
people/templates/people/map.html Normal file → Executable file
View File

@@ -3,7 +3,7 @@
{% block extra_head %} {% block extra_head %}
{{ map_markers|json_script:'map-markers' }} {{ map_markers|json_script:'map-markers' }}
{% load staticfiles %} {% load static %}
<script src="{% static 'js/map.js' %}"></script> <script src="{% static 'js/map.js' %}"></script>
<script async defer <script async defer

2
people/templates/people/network.html Normal file → Executable file
View File

@@ -97,6 +97,6 @@
integrity="sha512-Qlv6VSKh1gDKGoJbnyA5RMXYcvnpIqhO++MhIM2fStMcGT9i2T//tSwYFlcyoRRDcDZ+TYHpH8azBBCyhpSeqw==" integrity="sha512-Qlv6VSKh1gDKGoJbnyA5RMXYcvnpIqhO++MhIM2fStMcGT9i2T//tSwYFlcyoRRDcDZ+TYHpH8azBBCyhpSeqw=="
crossorigin="anonymous"></script> crossorigin="anonymous"></script>
{% load staticfiles %} {% load static %}
<script src="{% static 'js/network.js' %}"></script> <script src="{% static 'js/network.js' %}"></script>
{% endblock %} {% endblock %}

2
people/templates/people/organisation/detail.html Normal file → Executable file
View File

@@ -3,7 +3,7 @@
{% block extra_head %} {% block extra_head %}
{{ map_markers|json_script:'map-markers' }} {{ map_markers|json_script:'map-markers' }}
{% load staticfiles %} {% load static %}
<script src="{% static 'js/map.js' %}"></script> <script src="{% static 'js/map.js' %}"></script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key={{ settings.GOOGLE_MAPS_API_KEY }}&callback=initMap" <script async defer src="https://maps.googleapis.com/maps/api/js?key={{ settings.GOOGLE_MAPS_API_KEY }}&callback=initMap"

2
people/templates/people/organisation/update.html Normal file → Executable file
View File

@@ -1,7 +1,7 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block extra_head %} {% block extra_head %}
{% load staticfiles %} {% load static %}
{{ map_markers|json_script:'map-markers' }} {{ map_markers|json_script:'map-markers' }}
<script src="{% static 'js/map.js' %}"></script> <script src="{% static 'js/map.js' %}"></script>

10
people/templates/people/person/detail_full.html Normal file → Executable file
View File

@@ -3,7 +3,7 @@
{% block extra_head %} {% block extra_head %}
{{ map_markers|json_script:'map-markers' }} {{ map_markers|json_script:'map-markers' }}
{% load staticfiles %} {% load static %}
<script src="{% static 'js/map.js' %}"></script> <script src="{% static 'js/map.js' %}"></script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key={{ settings.GOOGLE_MAPS_API_KEY }}&callback=initMap" <script async defer src="https://maps.googleapis.com/maps/api/js?key={{ settings.GOOGLE_MAPS_API_KEY }}&callback=initMap"
@@ -64,16 +64,18 @@
<a class="btn btn-success" <a class="btn btn-success"
href="{% url 'people:person.update' pk=person.pk %}">Update</a> href="{% url 'people:person.update' pk=person.pk %}">Update</a>
{% load hijack_tags %} {% load hijack %}
{% if person.user == request.user and not request|is_hijacked %} {% if person.user == request.user and not request.user.is_hijacked %}
<a class="btn btn-info" <a class="btn btn-info"
href="{% url 'password_change' %}?next={{ person.get_absolute_url }}">Change Password</a> href="{% url 'password_change' %}?next={{ person.get_absolute_url }}">Change Password</a>
{% endif %} {% endif %}
{% if request.user.is_superuser and person.user and person.user != request.user %} {% if request.user.is_superuser and person.user and person.user != request.user %}
<form style="display: inline;" action="/hijack/{{ person.user.pk }}/" method="post"> <form action="{% url 'hijack:acquire' %}" method="POST">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="user_pk" value="{{ person.pk }}">
<button class="btn btn-warning" type="submit">Become {{ person.name }}</button> <button class="btn btn-warning" type="submit">Become {{ person.name }}</button>
<input type="hidden" name="next" value="{{ request.path }}">
</form> </form>
{% endif %} {% endif %}

2
people/templates/people/person/detail_partial.html Normal file → Executable file
View File

@@ -3,7 +3,7 @@
{% block extra_head %} {% block extra_head %}
{{ map_markers|json_script:'map-markers' }} {{ map_markers|json_script:'map-markers' }}
{% load staticfiles %} {% load static %}
<script src="{% static 'js/map.js' %}"></script> <script src="{% static 'js/map.js' %}"></script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key={{ settings.GOOGLE_MAPS_API_KEY }}&callback=initMap" <script async defer src="https://maps.googleapis.com/maps/api/js?key={{ settings.GOOGLE_MAPS_API_KEY }}&callback=initMap"

2
people/templates/people/person/update.html Normal file → Executable file
View File

@@ -1,7 +1,7 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block extra_head %} {% block extra_head %}
{% load staticfiles %} {% load static %}
{{ map_markers|json_script:'map-markers' }} {{ map_markers|json_script:'map-markers' }}
<script src="{% static 'js/map.js' %}"></script> <script src="{% static 'js/map.js' %}"></script>

2
people/templates/people/relationship/update.html Normal file → Executable file
View File

@@ -23,6 +23,6 @@
{% endblock %} {% endblock %}
{% block extra_script %} {% block extra_script %}
{% load staticfiles %} {% load static %}
<script async defer src="{% static 'js/hide_free_text.js' %}"></script> <script async defer src="{% static 'js/hide_free_text.js' %}"></script>
{% endblock %} {% endblock %}

75
requirements.txt Normal file → Executable file
View File

@@ -1,46 +1,45 @@
astroid==2.3.3 astroid==2.12.13
beautifulsoup4==4.8.2 beautifulsoup4==4.11.1
dj-database-url==0.5.0 dj-database-url==1.2.0
Django==2.2.10 Django==4.1.4
django-appconf==1.0.3 django-appconf==1.0.5
django-bootstrap4==1.1.1 django-bootstrap4==22.3
django-bootstrap-datepicker-plus==3.0.5 django-bootstrap-datepicker-plus==5.0.2
django-compat==1.0.15 django-constance==2.9.1
django-constance==2.6.0 django-countries==7.5
django-countries==5.5 django-dbbackup==4.0.2
django-dbbackup==3.2.0 django-filter==22.1
django-filter==2.2.0 django-hijack==3.2.6
django-hijack==2.2.1 django-picklefield==3.1
django-picklefield==2.1.1 django-post-office==3.6.3
django-post-office==3.4.0 django-select2==8.0.0
django-select2==7.2.0
django-settings-export==1.2.1 django-settings-export==1.2.1
djangorestframework==3.11.0 djangorestframework==3.14.0
dodgy==0.2.1 dodgy==0.2.1
isort==4.3.21 isort==5.11.4
jsonfield==3.1.0 jsonfield==3.1.0
lazy-object-proxy==1.4.3 lazy-object-proxy==1.8.0
mccabe==0.6.1 mccabe==0.7.0
# mysqlclient==1.4.6 # mysqlclient==1.4.6
pep8-naming==0.4.1 pep8-naming==0.10.0
prospector==1.2.0 prospector==1.8.3
pycodestyle==2.4.0 pycodestyle==2.10.0
pydocstyle==5.0.2 pydocstyle==6.1.1
pyflakes==2.1.1 pyflakes==2.5.0
pylint==2.4.4 pylint==2.15.9
pylint-celery==0.3 pylint-celery==0.3
pylint-django==2.0.12 pylint-django==2.5.3
pylint-flask==0.6 pylint-flask==0.6
pylint-plugin-utils==0.6 pylint-plugin-utils==0.7
python-decouple==3.3 python-decouple==3.6
pytz==2019.3 pytz==2022.7
pyuca==1.2 pyuca==1.2
PyYAML==5.3 PyYAML==6.0
requirements-detector==0.6 requirements-detector==1.0.3
setoptconf==0.2.0 setoptconf==0.3.0
six==1.14.0 six==1.16.0
snowballstemmer==2.0.0 snowballstemmer==2.2.0
soupsieve==1.9.5 soupsieve==2.3.2.post1
sqlparse==0.3.0 sqlparse==0.4.3
typed-ast typed-ast
wrapt==1.11.2 wrapt==1.14.1