user registration, ponyconf{user, speaker} models
This commit is contained in:
parent
e778f87bf6
commit
21d65e936d
|
@ -1,6 +1,6 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from accounts.models import *
|
||||
from accounts.models import PonyConfUser
|
||||
|
||||
|
||||
admin.site.register(User)
|
||||
admin.site.register(PonyConfUser)
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
from django.forms.models import modelform_factory
|
||||
from django.contrib.auth.forms import UserCreationForm
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from accounts.models import User
|
||||
from .models import PonyConfUser
|
||||
|
||||
|
||||
__all__ = ['ProfileForm']
|
||||
__all__ = ['ProfileForm', 'PonyConfUserForm']
|
||||
|
||||
|
||||
ProfileForm = modelform_factory(User,
|
||||
fields=['first_name', 'last_name', 'email', 'biography'])
|
||||
fields=['first_name', 'last_name', 'email', 'username'])
|
||||
|
||||
class CustomUserCreationForm(UserCreationForm):
|
||||
|
||||
class Meta(UserCreationForm.Meta):
|
||||
model = User
|
||||
fields = UserCreationForm.Meta.fields + ('biography',)
|
||||
PonyConfUserForm = modelform_factory(PonyConfUser,
|
||||
fields=['biography'])
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.6 on 2016-06-02 21:26
|
||||
# Generated by Django 1.9.7 on 2016-06-11 12:23
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import django.contrib.auth.models
|
||||
import django.core.validators
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
@ -13,35 +12,16 @@ class Migration(migrations.Migration):
|
|||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('auth', '0007_alter_validators_add_error_messages'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='User',
|
||||
name='PonyConfUser',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, unique=True, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.')], verbose_name='username')),
|
||||
('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
|
||||
('last_name', models.CharField(blank=True, max_length=30, verbose_name='last name')),
|
||||
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
|
||||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||
('bio', models.TextField(blank=True)),
|
||||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
|
||||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'verbose_name': 'user',
|
||||
'verbose_name_plural': 'users',
|
||||
},
|
||||
managers=[
|
||||
('objects', django.contrib.auth.models.UserManager()),
|
||||
('biography', models.TextField(blank=True, verbose_name='Biography')),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.6 on 2016-06-02 21:28
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('accounts', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='user',
|
||||
name='bio',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='biography',
|
||||
field=models.TextField(blank=True, verbose_name='Biography'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,40 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.7 on 2016-06-11 13:05
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import django.contrib.sites.managers
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.db.models.manager
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('sites', '0002_alter_domain_unique'),
|
||||
('accounts', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='PonyConfSpeaker',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('arrival', models.DateTimeField(blank=True, null=True)),
|
||||
('departure', models.DateTimeField(blank=True, null=True)),
|
||||
('transport', models.IntegerField(blank=True, choices=[(1, 'train'), (2, 'plane')], null=True)),
|
||||
('connector', models.IntegerField(blank=True, choices=[(1, 'VGA'), (2, 'HDMI'), (3, 'miniDP')], null=True)),
|
||||
('constraints', models.TextField()),
|
||||
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounts.PonyConfUser')),
|
||||
],
|
||||
managers=[
|
||||
('objects', django.db.models.manager.Manager()),
|
||||
('on_site', django.contrib.sites.managers.CurrentSiteManager()),
|
||||
],
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='ponyconfspeaker',
|
||||
unique_together=set([('site', 'user')]),
|
||||
),
|
||||
]
|
|
@ -1,11 +1,47 @@
|
|||
from enum import IntEnum
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.sites.models import Site
|
||||
from django.contrib.sites.managers import CurrentSiteManager
|
||||
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
|
||||
__all__ = [ 'User' ]
|
||||
__all__ = [ 'PonyConfUser', 'PonyConfSpeaker' ]
|
||||
|
||||
|
||||
class User(AbstractUser):
|
||||
def enum_to_choices(enum):
|
||||
return ((item.value, item.name) for item in list(enum))
|
||||
|
||||
class PonyConfUser(models.Model):
|
||||
|
||||
user = models.OneToOneField(User)
|
||||
biography = models.TextField(blank=True, verbose_name='Biography')
|
||||
|
||||
|
||||
class PonyConfSpeaker(models.Model):
|
||||
|
||||
TRANSPORTS = IntEnum('Transport', 'train plane')
|
||||
CONNECTORS = IntEnum('Connector', 'VGA HDMI miniDP')
|
||||
|
||||
site = models.ForeignKey(Site, on_delete=models.CASCADE)
|
||||
|
||||
user = models.ForeignKey(PonyConfUser)
|
||||
arrival = models.DateTimeField(blank=True, null=True)
|
||||
departure = models.DateTimeField(blank=True, null=True)
|
||||
transport = models.IntegerField(choices=enum_to_choices(TRANSPORTS), blank=True, null=True)
|
||||
connector = models.IntegerField(choices=enum_to_choices(CONNECTORS), blank=True, null=True)
|
||||
constraints = models.TextField()
|
||||
|
||||
objects = models.Manager()
|
||||
on_site = CurrentSiteManager()
|
||||
|
||||
class Meta:
|
||||
unique_together = ('site', 'user')
|
||||
|
||||
|
||||
def create_ponyconfuser(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
PonyConfUser.objects.create(user=instance)
|
||||
|
||||
models.signals.post_save.connect(create_ponyconfuser, sender=User, weak=False, dispatch_uid='create_ponyconfuser')
|
||||
|
|
|
@ -15,27 +15,14 @@
|
|||
<h3>Update profile</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form method="post" class="col-md-4" role="form">
|
||||
<form method="post" class="form-horizontal" role="form">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form profileform %}
|
||||
<div class="form-group">
|
||||
<button type="submit" name='update-profile' class="btn btn-primary">Update</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3>Update password</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form method="post" class="col-md-4" role="form">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form passwordform %}
|
||||
<div class="form-group">
|
||||
<button type="submit" name='update-password' class="btn btn-primary">Update</button>
|
||||
</div>
|
||||
{% for form in forms %}
|
||||
{% bootstrap_form form layout="horizontal" %}
|
||||
{% endfor %}
|
||||
{% buttons layout="horizontal" %}
|
||||
<button type="submit" class="btn btn-primary">Update</button>
|
||||
{% endbuttons %}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,36 +1,29 @@
|
|||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.forms import PasswordChangeForm
|
||||
from django.contrib.auth.views import password_change
|
||||
from django.contrib import messages
|
||||
|
||||
from accounts.forms import *
|
||||
from .forms import ProfileForm, PonyConfUserForm
|
||||
|
||||
|
||||
@login_required
|
||||
def password(request):
|
||||
return password_change(request, post_change_redirect='profile')
|
||||
|
||||
|
||||
@login_required
|
||||
def profile(request):
|
||||
profileform = None
|
||||
passwordform = None
|
||||
|
||||
forms = [ProfileForm(request.POST or None, instance=request.user),
|
||||
PonyConfUserForm(request.POST or None, instance=request.user.ponyconfuser)]
|
||||
|
||||
if request.method == 'POST':
|
||||
if 'update-profile' in request.POST:
|
||||
profileform = ProfileForm(request.POST, instance=request.user)
|
||||
if profileform.is_valid():
|
||||
profileform.save()
|
||||
messages.success(request, 'Profile updated successfully.')
|
||||
return redirect('profile')
|
||||
elif 'update-password' in request.POST:
|
||||
passwordform = PasswordChangeForm(user=request.user, data=request.POST)
|
||||
if passwordform.is_valid():
|
||||
passwordform.save()
|
||||
messages.success(request, 'Password updated successfully.')
|
||||
return redirect('profile')
|
||||
if all(form.is_valid() for form in forms):
|
||||
for form in forms:
|
||||
form.save()
|
||||
messages.success(request, 'Profile updated successfully.')
|
||||
else:
|
||||
messages.error(request, 'Please correct those errors.')
|
||||
|
||||
if not profileform:
|
||||
profileform = ProfileForm(None, instance=request.user)
|
||||
if not passwordform:
|
||||
passwordform = PasswordChangeForm(None)
|
||||
|
||||
return render(request, 'accounts/profile.html', {
|
||||
'profileform': profileform,
|
||||
'passwordform': passwordform,
|
||||
})
|
||||
return render(request, 'accounts/profile.html', {'forms': forms})
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
- [x] enregistrement sur le site (pas d'enregistrement fb/linkedin: on aime le libre ici)
|
||||
- [ ] permettre de proposer une participation (conférence/atelier/small talk/etc.). Un speaker rentre un abstract et
|
||||
peur associer un ou des co-speakers.
|
||||
- [ ] l'équipe organisatrice peut voter pour les conférences (avec un commentaire visible uniquement de l'équipe) et
|
||||
les accepter/refuser
|
||||
- [ ] pour chaque conférence/conférencier, on permet d'échanger avec le conférencier (lui vois ça comme un mail, mais
|
||||
côté orga c'est centralisé sur l'UI web... c'est mieux pour le suivi).
|
||||
- [ ] Notification (par mail) pour les administrateurs des ajout/modification de conférence et des échanges avec les
|
||||
intervenants.
|
||||
- [ ] Gestion du planning des salles (on affecte une track à une salle, mais cela permet surtout de signaler les
|
||||
doublons d'intervenants/salle/etc.)
|
||||
- [ ] Gestion du planning des bénévoles (ils s'inscrivent)
|
||||
- [ ] Générer un planning XML pour être ingérée par l'appli Android
|
||||
- [ ] Gestion de différents profils: speaker, bénévole, responsable de track, kernel
|
||||
- [ ] Génération des badges
|
||||
- [x] Un speaker et un bénévole peuvent être enregistré par un tiers (responsable de track ou kernel).
|
||||
- [ ] Gestion des sponsors : niveaux de sponsorings et personnes présentes pour la génération des badges
|
||||
- [ ] Gestion des différentes thématiques (CRUD)
|
||||
- [ ] Vues à réaliser: listing des propositions, conférence, bénévoles, speakers (permet d'avoir une vue d'ensemble)
|
||||
- [ ] Champ de note interne sur un speaker (pour noter des préférences par exemple) et sur une proposition de
|
||||
conférence
|
||||
- [ ] Gestion de la date d'ouverture/fermeture de l'appel à conférence (différente selon le type de participation -
|
||||
i.e. conférence/atelier/stand).
|
||||
- [ ] On propose par défaut des propositions du type: talk, workshop, booth
|
||||
- [x] Profil des intervenenants: nom, prénom, mail, date et heure d'arrivée, date et heure de départ, moyen de
|
||||
transport, type de connectique, hébergement,
|
||||
- [ ] Possibilité aux intervenants de récupérer leur billet d’avion électronique
|
||||
- [ ] Aide au planning :
|
||||
- [x] affichage des contraintes des intervenants
|
||||
- [ ] qui est disponible pour un time slot donnée
|
||||
- [ ] Stand ?
|
||||
|
||||
Le code de l'année dernière est là : https://github.com/toulibre/cdl-site
|
|
@ -1,41 +0,0 @@
|
|||
- enregistrement sur le site (pas d'enregistrement fb/linkedin: on aime
|
||||
le libre ici)
|
||||
- permettre de proposer une participation (conférence/atelier/small
|
||||
talk/etc.). Un speaker rentre un abstract et peur associer un ou des
|
||||
co-speakers.
|
||||
- l'équipe organisatrice peut voter pour les conférences (avec un
|
||||
commentaire visible uniquement de l'équipe) et les accepter/refuser
|
||||
- pour chaque conférence/conférencier, on permet d'échanger avec le
|
||||
conférencier (lui vois ça comme un mail, mais côté orga c'est centralisé
|
||||
sur l'UI web... c'est mieux pour le suivi).
|
||||
- Notification (par mail) pour les administrateurs des
|
||||
ajout/modification de conférence et des échanges avec les intervenants.
|
||||
- Gestion du planning des salles (on affecte une track à une salle, mais
|
||||
cela permet surtout de signaler les doublons d'intervenants/salle/etc.)
|
||||
- Gestion du planning des bénévoles (ils s'inscrivent)
|
||||
- Générer un planning XML pour être ingérée par l'appli Android
|
||||
- Gestion de différents profils: speaker, bénévole, responsable de
|
||||
track, kernel
|
||||
- Génération des badges
|
||||
- Un speaker et un bénévole peuvent être enregistré par un tiers
|
||||
(responsable de track ou kernel).
|
||||
- Gestion des sponsors : niveaux de sponsorings et personnes présentes
|
||||
pour la génération des badges
|
||||
- Gestion des différentes thématiques (CRUD)
|
||||
- Vues à réaliser: listing des propositions, conférence, bénévoles,
|
||||
speakers (permet d'avoir une vue d'ensemble)
|
||||
- Champ de note interne sur un speaker (pour noter des préférences par
|
||||
exemple) et sur une proposition de conférence
|
||||
- Gestion de la date d'ouverture/fermeture de l'appel à conférence
|
||||
(différente selon le type de participation - i.e. conférence/atelier/stand).
|
||||
- On propose par défaut des propositions du type: talk, workshop, booth
|
||||
- Profil des intervenenants: nom, prénom, mail, date et heure d'arrivée,
|
||||
date et heure de départ, moyen de transport, type de connectique,
|
||||
hébergement,
|
||||
- Possibilité aux intervenants de récupérer leur billet d’avion
|
||||
électronique
|
||||
- Aide au planning : affichage des contraintes des intervenants, qui est
|
||||
disponible pour un time slot donnée, …
|
||||
- Stand ?
|
||||
|
||||
Le code de l'annéed ernière est là : https://github.com/toulibre/cdl-site
|
|
@ -32,6 +32,7 @@ ALLOWED_HOSTS = []
|
|||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'registration',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
|
@ -146,8 +147,6 @@ LOGIN_REDIRECT_URL = 'home'
|
|||
|
||||
SITE_ID = 1
|
||||
|
||||
AUTH_USER_MODEL = 'accounts.User'
|
||||
|
||||
BOOTSTRAP3 = {
|
||||
|
||||
# The URL to the jQuery JavaScript file
|
||||
|
|
|
@ -20,5 +20,6 @@ from django.contrib import admin
|
|||
urlpatterns = [
|
||||
url(r'^admin/', admin.site.urls),
|
||||
url(r'^accounts/', include('accounts.urls')),
|
||||
url(r'^registration/', include('registration.backends.default.urls')),
|
||||
url(r'^', include('proposals.urls')),
|
||||
]
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.7 on 2016-06-11 13:05
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('proposals', '0003_auto_20160608_2002'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='speach',
|
||||
options={'ordering': ['talk', 'order']},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='speach',
|
||||
name='user',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounts.PonyConfSpeaker'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='talk',
|
||||
name='speakers',
|
||||
field=models.ManyToManyField(through='proposals.Speach', to='accounts.PonyConfSpeaker'),
|
||||
),
|
||||
]
|
|
@ -4,7 +4,7 @@ from django.contrib.sites.managers import CurrentSiteManager
|
|||
|
||||
from autoslug import AutoSlugField
|
||||
|
||||
from accounts.models import User
|
||||
from accounts.models import PonyConfSpeaker
|
||||
|
||||
|
||||
__all__ = [ 'Topic', 'Talk', 'Speach' ]
|
||||
|
@ -14,12 +14,12 @@ class Topic(models.Model):
|
|||
|
||||
site = models.ForeignKey(Site, on_delete=models.CASCADE)
|
||||
|
||||
objects = models.Manager()
|
||||
on_site = CurrentSiteManager()
|
||||
|
||||
name = models.CharField(max_length=128, verbose_name='Name', unique=True)
|
||||
slug = AutoSlugField(populate_from='name', unique=True)
|
||||
|
||||
objects = models.Manager()
|
||||
on_site = CurrentSiteManager()
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
@ -28,29 +28,29 @@ class Talk(models.Model):
|
|||
|
||||
site = models.ForeignKey(Site, on_delete=models.CASCADE)
|
||||
|
||||
objects = models.Manager()
|
||||
on_site = CurrentSiteManager()
|
||||
|
||||
speakers = models.ManyToManyField(User, through='Speach')
|
||||
speakers = models.ManyToManyField(PonyConfSpeaker, through='Speach')
|
||||
title = models.CharField(max_length=128, verbose_name='Title')
|
||||
slug = AutoSlugField(populate_from='title', unique=True)
|
||||
description = models.TextField(blank=True, verbose_name='Description')
|
||||
topics = models.ManyToManyField(Topic, blank=True)
|
||||
|
||||
objects = models.Manager()
|
||||
on_site = CurrentSiteManager()
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
|
||||
class Speach(models.Model):
|
||||
|
||||
SPEAKER_NO = ((1, "1"), (2, "2"), (3, "3"), (4, "4"), (5, "5"), (6, "6"), (7, "7"),)
|
||||
SPEAKER_NO = tuple((i, str(i)) for i in range(1, 8))
|
||||
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
user = models.ForeignKey(PonyConfSpeaker, on_delete=models.CASCADE)
|
||||
talk = models.ForeignKey(Talk, on_delete=models.CASCADE)
|
||||
order = models.IntegerField(choices=SPEAKER_NO)
|
||||
|
||||
class Meta:
|
||||
ordering = [ 'order' ]
|
||||
ordering = ['talk', 'order']
|
||||
unique_together = (
|
||||
('user', 'talk'),
|
||||
('order', 'talk'),
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<ul>
|
||||
{% for speaker in talk.speakers.all %}
|
||||
<li>
|
||||
<a href="{% url 'show-user' speaker.username %}">
|
||||
<a href="{% url 'show-user' speaker.user.user.username %}">
|
||||
{% firstof speaker.get_full_name speaker.username %}
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<a href="{% url 'show-talk' talk.slug %}">{{ talk }}</a>
|
||||
<i>by</i>
|
||||
{% for speach in talk.speach_set.all %}
|
||||
<a href="{% url 'show-user' speach.user.username %}">{% firstof speach.user.get_full_name speach.user.username %}</a>
|
||||
<a href="{% url 'show-user' speach.user.user.user.username %}">{% firstof speach.user.user.user.get_full_name speach.user.user.user.username %}</a>
|
||||
{% if forloop.revcounter == 2 %} and {% elif not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
<a class="btn btn-primary" href="{% url 'edit-talk' talk.slug %}">edit</a>
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
<b>Biography:</b>
|
||||
<p>{{ user.biography }}</p>
|
||||
|
||||
<a href="{% url 'list-talks-by-speaker' user.username %}">See the list of talks with this speaker</a>
|
||||
<a href="{% url 'list-talks-by-speaker' user.user.username %}">See the list of talks with this speaker</a>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -14,9 +14,14 @@ def home(request):
|
|||
|
||||
@login_required
|
||||
def talk_list(request):
|
||||
talks = Talk.on_site.all()
|
||||
mine = talks.filter(speakers=request.user)
|
||||
others = talks.exclude(speakers=request.user)
|
||||
speaker = PonyConfSpeaker.on_site.filter(user=request.user.ponyconfuser)
|
||||
if speaker.exists():
|
||||
speaker = speaker.first()
|
||||
mine = Talk.on_site.filter(speakers=speaker)
|
||||
others = Talk.on_site.exclude(speakers=speaker)
|
||||
else:
|
||||
mine = []
|
||||
others = Talk.on_site.all()
|
||||
return render(request, 'proposals/talks.html', {
|
||||
'my_talks': mine,
|
||||
'other_talks': others,
|
||||
|
@ -33,7 +38,7 @@ def talk_list_by_topic(request, topic):
|
|||
|
||||
@login_required
|
||||
def talk_list_by_speaker(request, speaker):
|
||||
speaker = get_object_or_404(User, username=speaker)
|
||||
speaker = get_object_or_404(PonyConfSpeaker, user__user__username=speaker)
|
||||
talks = Talk.on_site.filter(speakers=speaker)
|
||||
return render(request, 'proposals/talk_list.html', {
|
||||
'title': 'Talks with %s:' % (speaker.get_full_name() or speaker.username),
|
||||
|
@ -50,14 +55,16 @@ def talk_edit(request, talk=None):
|
|||
raise PermissionDenied()
|
||||
form = TalkForm(request.POST or None, instance=talk)
|
||||
if request.method == 'POST' and form.is_valid():
|
||||
if talk:
|
||||
if hasattr(talk, 'id'):
|
||||
talk = form.save()
|
||||
messages.success(request, 'Talk modified successfully!')
|
||||
else:
|
||||
site = get_current_site(request)
|
||||
talk = form.save(commit=False)
|
||||
talk.site = get_current_site(request)
|
||||
talk.site = site
|
||||
talk.save()
|
||||
speach = Speach(user=request.user,talk=talk,order=1)
|
||||
speaker = PonyConfSpeaker.on_site.get_or_create(user=request.user.ponyconfuser, site=site)[0]
|
||||
speach = Speach(user=speaker, talk=talk, order=1)
|
||||
speach.save()
|
||||
messages.success(request, 'Talk proposed successfully!')
|
||||
return redirect('show-talk', talk.slug)
|
||||
|
@ -81,15 +88,14 @@ def topic_list(request):
|
|||
|
||||
@login_required
|
||||
def speaker_list(request):
|
||||
talks = Talk.on_site.all()
|
||||
speakers = User.objects.filter(talks__in=talks) # FIXME
|
||||
speakers = PonyConfSpeaker.on_site.all()
|
||||
return render(request, 'proposals/speaker_list.html', {
|
||||
'speaker': speakers,
|
||||
})
|
||||
|
||||
@login_required
|
||||
def user_details(request, username):
|
||||
user = get_object_or_404(User, username=username)
|
||||
user = get_object_or_404(PonyConfUser, user__username=username)
|
||||
return render(request, 'proposals/user_details.html', {
|
||||
'user': user,
|
||||
})
|
||||
|
|
|
@ -2,3 +2,4 @@ django<1.10
|
|||
django-bower
|
||||
django-bootstrap3
|
||||
django-autoslug
|
||||
django-registration-redux
|
||||
|
|
Loading…
Reference in New Issue