mirror of
https://github.com/Southampton-RSG/breccia-mapper.git
synced 2026-03-03 03:17:07 +00:00
feat(people): Add view to create Person
User profile nav directs to create new Person for user if there is not one currently associated resolves issue #4
This commit is contained in:
@@ -60,6 +60,10 @@
|
|||||||
|
|
||||||
<div class="navbar-collapse collapse" id="navbarCollapse">
|
<div class="navbar-collapse collapse" id="navbarCollapse">
|
||||||
<ul class="navbar-nav mt-2 mt-lg-0">
|
<ul class="navbar-nav mt-2 mt-lg-0">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="{% url 'people:person.list' %}" class="nav-link">People</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
{% if request.user.is_superuser %}
|
{% if request.user.is_superuser %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="{% url 'admin:index' %}" class="nav-link">Admin</a>
|
<a href="{% url 'admin:index' %}" class="nav-link">Admin</a>
|
||||||
@@ -71,19 +75,20 @@
|
|||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
{% if request.user.person %}
|
{% if request.user.person %}
|
||||||
<a href="{{ request.user.get_absolute_url }}" class="nav-link">
|
<a href="{% url 'people:person.profile' %}" class="nav-link">
|
||||||
<i class="fas fa-user-circle"></i>
|
<i class="fas fa-user-circle"></i>
|
||||||
{{ request.user }}
|
{{ request.user }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="navbar-text">
|
<a href="{% url 'people:person.create' %}?user" class="nav-link">
|
||||||
<i class="fas fa-user-circle"></i>
|
<i class="fas fa-user-circle"></i>
|
||||||
{{ request.user }}
|
{{ request.user }}
|
||||||
</span>
|
</a>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<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="fas fa-sign-out-alt"></i>
|
||||||
|
|||||||
19
people/forms.py
Normal file
19
people/forms.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
"""
|
||||||
|
Forms for creating / updating models belonging to the 'people' app.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django import forms
|
||||||
|
|
||||||
|
from . import models
|
||||||
|
|
||||||
|
|
||||||
|
class PersonForm(forms.ModelForm):
|
||||||
|
"""
|
||||||
|
Form for creating / updating an instance of :class:`Person`.
|
||||||
|
"""
|
||||||
|
class Meta:
|
||||||
|
model = models.Person
|
||||||
|
fields = [
|
||||||
|
'name',
|
||||||
|
'core_member',
|
||||||
|
]
|
||||||
20
people/migrations/0004_person_user.py
Normal file
20
people/migrations/0004_person_user.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 2.2.10 on 2020-02-18 15:44
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('people', '0003_fix_people_plural'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='person',
|
||||||
|
name='user',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='person', to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
]
|
||||||
20
people/migrations/0005_user_one_person.py
Normal file
20
people/migrations/0005_user_one_person.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 2.2.10 on 2020-02-19 08:09
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('people', '0004_person_user'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='person',
|
||||||
|
name='user',
|
||||||
|
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='person', to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
|
||||||
class User(AbstractUser):
|
class User(AbstractUser):
|
||||||
@@ -12,10 +14,15 @@ class Person(models.Model):
|
|||||||
"""
|
"""
|
||||||
A person may be a member of the BRECcIA core team or an external stakeholder.
|
A person may be a member of the BRECcIA core team or an external stakeholder.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name_plural = 'people'
|
verbose_name_plural = 'people'
|
||||||
|
|
||||||
|
#: User account belonging to this person
|
||||||
|
user = models.OneToOneField(settings.AUTH_USER_MODEL,
|
||||||
|
related_name='person',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
blank=True, null=True)
|
||||||
|
|
||||||
#: Name of the person
|
#: Name of the person
|
||||||
name = models.CharField(max_length=255,
|
name = models.CharField(max_length=255,
|
||||||
blank=False, null=False)
|
blank=False, null=False)
|
||||||
@@ -36,6 +43,9 @@ class Person(models.Model):
|
|||||||
self.relationships_as_target.all()
|
self.relationships_as_target.all()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse('people:person.detail', kwargs={'pk': self.pk})
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|||||||
27
people/templates/people/person/create.html
Normal file
27
people/templates/people/person/create.html
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="{% url 'people:person.list' %}">People</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item active" aria-current="page">Create</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<form class="form"
|
||||||
|
method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
{% load bootstrap4 %}
|
||||||
|
{% bootstrap_form form %}
|
||||||
|
|
||||||
|
{% buttons %}
|
||||||
|
<button class="btn btn-success" type="submit">Submit</button>
|
||||||
|
{% endbuttons %}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -10,6 +10,10 @@ urlpatterns = [
|
|||||||
views.ProfileView.as_view(),
|
views.ProfileView.as_view(),
|
||||||
name='person.profile'),
|
name='person.profile'),
|
||||||
|
|
||||||
|
path('people/create',
|
||||||
|
views.PersonCreateView.as_view(),
|
||||||
|
name='person.create'),
|
||||||
|
|
||||||
path('people',
|
path('people',
|
||||||
views.PersonListView.as_view(),
|
views.PersonListView.as_view(),
|
||||||
name='person.list'),
|
name='person.list'),
|
||||||
|
|||||||
@@ -2,9 +2,26 @@
|
|||||||
Views for displaying or manipulating models in the 'people' app.
|
Views for displaying or manipulating models in the 'people' app.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.views.generic import DetailView, ListView
|
from django.views.generic import CreateView, DetailView, ListView
|
||||||
|
|
||||||
from . import models
|
from . import forms, models
|
||||||
|
|
||||||
|
|
||||||
|
class PersonCreateView(CreateView):
|
||||||
|
"""
|
||||||
|
View to create a new instance of :class:`Person`.
|
||||||
|
|
||||||
|
If 'user' is passed as a URL parameter - link the new person to the current user.
|
||||||
|
"""
|
||||||
|
model = models.Person
|
||||||
|
template_name = 'people/person/create.html'
|
||||||
|
form_class = forms.PersonForm
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
if 'user' in self.request.GET:
|
||||||
|
form.instance.user = self.request.user
|
||||||
|
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
class PersonListView(ListView):
|
class PersonListView(ListView):
|
||||||
@@ -22,6 +39,18 @@ class ProfileView(DetailView):
|
|||||||
model = models.Person
|
model = models.Person
|
||||||
template_name = 'people/person/detail.html'
|
template_name = 'people/person/detail.html'
|
||||||
|
|
||||||
|
def get_object(self, queryset=None) -> models.Person:
|
||||||
|
"""
|
||||||
|
Get the :class:`Person` object to be represented by this page.
|
||||||
|
|
||||||
|
If not determined from url get current user.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return super().get_object(queryset)
|
||||||
|
|
||||||
|
except AttributeError:
|
||||||
|
return self.request.user.person
|
||||||
|
|
||||||
|
|
||||||
class RelationshipDetailView(DetailView):
|
class RelationshipDetailView(DetailView):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user