Commit 64791f08 authored by Bruno Martin's avatar Bruno Martin
Browse files

add user new fields, with migrations

parent 1528c249
......@@ -22,3 +22,6 @@
[submodule "ext-apps/django-discussion"]
path = ext-apps/django-discussion
url = git@github.com:hacklabr/django-discussion.git
[submodule "ext-apps/django-messages-courier"]
path = ext-apps/django-messages-courier
url = git@github.com:hacklabr/django-messages-courier.git
# Generated by Django 2.1.7 on 2019-03-31 21:51
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0002_auto_20190307_2021'),
]
operations = [
migrations.CreateModel(
name='ActivismSchoolWorkplace',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True, verbose_name='Name')),
],
options={
'verbose_name': 'Activism School Workplace',
'verbose_name_plural': 'Activism School Workplaces',
},
),
migrations.CreateModel(
name='CtbRole',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True, verbose_name='Name')),
],
options={
'verbose_name': 'UJS Manager Role',
'verbose_name_plural': 'UJS Manager Roles',
},
),
migrations.CreateModel(
name='Event',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True, verbose_name='Name')),
],
options={
'verbose_name': 'Event',
'verbose_name_plural': 'Events',
},
),
migrations.CreateModel(
name='PoliticalFront',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True, verbose_name='Name')),
],
options={
'verbose_name': 'Political Front',
'verbose_name_plural': 'Political Fronts',
},
),
migrations.AddField(
model_name='user',
name='activism_school_workplace_other',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Other activism form in school and/or workplace'),
),
migrations.AddField(
model_name='user',
name='address',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Address'),
),
migrations.AddField(
model_name='user',
name='address_extra',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Extra information for address'),
),
migrations.AddField(
model_name='user',
name='address_number',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Address number'),
),
migrations.AddField(
model_name='user',
name='birth_date',
field=models.DateField(blank=True, null=True, verbose_name='Birth Date'),
),
migrations.AddField(
model_name='user',
name='has_mandate',
field=models.NullBooleanField(verbose_name='Has a mandate'),
),
migrations.AddField(
model_name='user',
name='mandate',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Mandate'),
),
migrations.AddField(
model_name='user',
name='neighborhood',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Neighborhood'),
),
migrations.AddField(
model_name='user',
name='phone_number',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Phone number'),
),
migrations.AddField(
model_name='user',
name='phone_number_other',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Other phone number'),
),
migrations.AddField(
model_name='user',
name='political_front_other',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Other political front'),
),
migrations.AddField(
model_name='user',
name='school',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='School'),
),
migrations.AddField(
model_name='user',
name='sexual_orientation',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Sexual orientation'),
),
migrations.AddField(
model_name='user',
name='sexual_orientation_other',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Other sexual orientation'),
),
migrations.AddField(
model_name='user',
name='social_facebook',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Facebook'),
),
migrations.AddField(
model_name='user',
name='social_google',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Google'),
),
migrations.AddField(
model_name='user',
name='social_skype',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Skype'),
),
migrations.AddField(
model_name='user',
name='social_twitter',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Twitter'),
),
migrations.AddField(
model_name='user',
name='studies',
field=models.NullBooleanField(verbose_name='Studies'),
),
migrations.AddField(
model_name='user',
name='zipcode',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='ZIP Code'),
),
migrations.AlterField(
model_name='user',
name='city',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='users', to='cities_light.City', verbose_name='City'),
),
migrations.AlterField(
model_name='user',
name='country',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='users', to='cities_light.Country', verbose_name='Country'),
),
migrations.AlterField(
model_name='user',
name='state',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='users', to='cities_light.Region', verbose_name='Region'),
),
migrations.AddField(
model_name='user',
name='activism_school_workplace',
field=models.ManyToManyField(blank=True, related_name='users', to='users.ActivismSchoolWorkplace', verbose_name='Activism in school and/or workplace'),
),
migrations.AddField(
model_name='user',
name='political_front',
field=models.ManyToManyField(blank=True, related_name='users', to='users.PoliticalFront', verbose_name='Political front'),
),
]
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import AbstractUser, Group
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from allauth.socialaccount.models import SocialAccount
from cities_light.models import City, Region, Country
import hashlib
class PoliticalFront(models.Model):
name = models.CharField(
_('Name'),
max_length=255,
unique=True
)
def __str__(self):
return self.name
class Meta:
verbose_name = _('Political Front')
verbose_name_plural = _('Political Fronts')
class ActivismSchoolWorkplace(models.Model):
name = models.CharField(
_('Name'),
max_length=255,
unique=True
)
def __str__(self):
return self.name
class Meta:
verbose_name = _('Activism School Workplace')
verbose_name_plural = _('Activism School Workplaces')
class Event(models.Model):
name = models.CharField(
_('Name'),
max_length=255,
unique=True
)
def __str__(self):
return self.name
class Meta:
verbose_name = _('Event')
verbose_name_plural = _('Events')
class CtbRole(models.Model):
name = models.CharField(
_('Name'),
max_length=255,
unique=True
)
def __str__(self):
return self.name
class Meta:
verbose_name = _('UJS Manager Role')
verbose_name_plural = _('UJS Manager Roles')
class User(AbstractUser):
RACE_CHOICES = (
......@@ -41,8 +102,16 @@ class User(AbstractUser):
('OTHER', _('Other'))
)
city = models.CharField(_('City'), null=True, blank=True, max_length=255)
state = models.CharField(_('State'), null=True, blank=True, max_length=255)
SEXUAL_ORIENTATION_CHOICES = (
('LESBICA', _('Lesbian')),
('GAY', _('Gay')),
('BISSEXUAL', _('Bissexual')),
('HETEROSSEXUAL', _('Heterossexual')),
('ASSEXUAL', _('Assexual')),
('FLUIDO', _('Fluid')),
('OTHER', _('Other'))
)
biography = models.TextField(_('Biography'), blank=True, null=True)
# First Name and Last Name do not cover name patterns
# around the globe.
......@@ -52,12 +121,6 @@ class User(AbstractUser):
max_length=255,
null=True
)
country = models.CharField(
_('Country'),
null=True,
blank=True,
max_length=255
)
occupation = models.CharField(
_('Occupation'),
null=True,
......@@ -82,6 +145,17 @@ class User(AbstractUser):
null=True, max_length=255,
blank=True
)
sexual_orientation = models.CharField(
_('Sexual orientation'),
null=True, max_length=255,
# choices=SEXUAL_ORIENTATION_CHOICES,
blank=True
)
sexual_orientation_other = models.CharField(
_('Other sexual orientation'),
null=True, max_length=255,
blank=True
)
race = models.CharField(
_('Race'),
null=True,
......@@ -89,8 +163,145 @@ class User(AbstractUser):
choices=RACE_CHOICES,
max_length=255
)
birth_date = models.DateField(
_('Birth Date'),
blank=True,
null=True
)
# Contact info
phone_number = models.CharField(
_('Phone number'),
null=True,
blank=True,
max_length=255
)
phone_number_other = models.CharField(
_('Other phone number'),
null=True,
blank=True,
max_length=255
)
# Localization info
address = models.CharField(
_('Address'),
null=True, max_length=255,
blank=True
)
address_number = models.CharField(
_('Address number'),
null=True, max_length=255,
blank=True
)
address_extra = models.CharField(
_('Extra information for address'),
null=True, max_length=255,
blank=True
)
neighborhood = models.CharField(
_('Neighborhood'),
null=True, max_length=255,
blank=True
)
zipcode = models.CharField(
_('ZIP Code'),
null=True, max_length=255,
blank=True
)
city = models.ForeignKey(
City,
models.CASCADE,
verbose_name=_('City'),
related_name='users',
null=True,
blank=True,
)
state = models.ForeignKey(
Region,
models.CASCADE,
verbose_name=_('Region'),
related_name='users',
null=True,
blank=True
)
country = models.ForeignKey(
Country,
models.CASCADE,
verbose_name=_('Country'),
related_name='users',
null=True,
blank=True,
)
# Social info
social_facebook = models.CharField(
_('Facebook'),
null=True, max_length=255,
blank=True
)
social_twitter = models.CharField(
_('Twitter'),
null=True, max_length=255,
blank=True
)
social_skype = models.CharField(
_('Skype'),
null=True, max_length=255,
blank=True
)
social_google = models.CharField(
_('Google'),
null=True, max_length=255,
blank=True
)
site = models.CharField(
_('Site'),
null=True, max_length=255,
blank=True
)
# Political info
political_front = models.ManyToManyField(
PoliticalFront,
verbose_name=_('Political front'),
related_name='users',
blank=True
)
political_front_other = models.CharField(
_('Other political front'),
null=True, max_length=255,
blank=True
)
studies = models.NullBooleanField(
_('Studies'),
blank=True
)
school = models.CharField(
_('School'),
null=True, max_length=255,
blank=True
)
activism_school_workplace = models.ManyToManyField(
ActivismSchoolWorkplace,
verbose_name=_('Activism in school and/or workplace'),
related_name='users',
blank=True
)
activism_school_workplace_other = models.CharField(
_('Other activism form in school and/or workplace'),
null=True, max_length=255,
blank=True
)
has_mandate = models.NullBooleanField(
_('Has a mandate'),
blank=True
)
mandate = models.CharField(
_('Mandate'),
null=True, max_length=255,
blank=True
)
# Legacy stuff
cpf = models.CharField(max_length=11, blank=True, null=True, unique=True)
institution = models.CharField(max_length=255, blank=True, null=True)
......@@ -131,7 +342,7 @@ class User(AbstractUser):
is_new = self.pk is None
super(AbstractTimtecUser, self).save(*args, **kwargs)
super().save(*args, **kwargs)
if is_new and settings.REGISTRATION_DEFAULT_GROUP_NAME:
try:
......
......@@ -7,7 +7,9 @@ from allauth.account.utils import setup_user_email
from allauth.account import app_settings as allauth_settings
from allauth.socialaccount.helpers import complete_social_login
from requests.exceptions import HTTPError
from cities_light.models import City, Region
from .models import PoliticalFront, ActivismSchoolWorkplace, CtbRole
User = get_user_model()
......@@ -20,30 +22,86 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
'occupation', 'is_superuser', )
class SimpleUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'image', 'name', 'biography')
class RegistrationSerializer(RegisterSerializer):
name = serializers.CharField()
name = serializers.CharField(max_length=255, required=False)
captcha = serializers.CharField(max_length=2048)
city = serializers.PrimaryKeyRelatedField(queryset=City.objects.all(),
allow_null=True)
state = serializers.PrimaryKeyRelatedField(queryset=Region.objects.all(),
allow_null=True)
phone_number = serializers.CharField(max_length=255, allow_null=True)
origin = serializers.CharField(max_length=30, required=False, allow_blank=True)
def get_cleaned_data(self):
return {
'first_name': self.validated_data.get('first_name', ''),
'last_name': self.validated_data.get('last_name', ''),
'name': self.validated_data.get('name', ''),
'username': self.validated_data.get('username', ''),
'password1': self.validated_data.get('password1', ''),
'email': self.validated_data.get('email', '')
'email': self.validated_data.get('email', ''),
'city': self.validated_data.get('city', None),
'state': self.validated_data.get('state', None),
'phone_number': self.validated_data.get('phone_number', ''),
'origin': self.validated_data.get('origin', 'signup')
}
def validate_captcha(self, attr):
captcha_req = requests.post('https://www.google.com/recaptcha/api/siteverify',
data = {
'secret': settings.RECAPTCHA_SECRET_KEY,
'response': attr
})
captcha_resp = captcha_req.json()
if not captcha_resp['success']:
raise serializers.ValidationError(_('Invalid CAPTCHA.'))
def custom_signup(self, request, user):
user.name = self.cleaned_data['name']
user.phone_number = self.cleaned_data['phone_number']
user.city = self.cleaned_data['city']
user.state = self.cleaned_data['state']
user.origin = self.cleaned_data['origin']
user.save()
def save(self, request):
adapter = get_adapter()
user = adapter.new_user(request)
self.cleaned_data = self.get_cleaned_data()
user.name = self.cleaned_data.get('name')
adapter.save_user(request, user, self)
self.custom_signup(request, user)
setup_user_email(request, user, [])
return user
class PoliticalFrontSerializer(serializers.ModelSerializer):
class Meta:
model = PoliticalFront
fields = ('id', 'name')
class ActivismSchoolWorkplaceSerializer(serializers.ModelSerializer):
class Meta:
model = ActivismSchoolWorkplace
fields = ('id', 'name')
class CtbRoleSerializer(serializers.ModelSerializer):
class Meta:
model = CtbRole
fields = ('id', 'name')
class FixSocialLoginSerializer(SocialLoginSerializer):
def validate(self, attrs):
view = self.context.get('view')
......
......@@ -8,7 +8,10 @@ from . import views
router = SimpleRouter()
router.register(r'', views.UserViewSet)
# router.register(r'^me/$', views.UserViewSet, base_name='me')
router.register(r'political-front', views.PoliticalFrontViewSet),
router.register(r'activism-school-workplace', views.ActivismSchoolWorkplaceViewSet),
router.register(r'org-role', views.CtbRoleViewSet),
# router.register(r'stats', views.StatsViewSet, base_name='user_stats'),
app_name = 'users'
urlpatterns = [
......@@ -17,7 +20,15 @@ urlpatterns = [
view=views.get_api_key,
name='api-key'
),
url(r'^close/$', TemplateView.as_view(template_name='users/close.html')),
url(
regex=r'^details/(?P<username>.*)/$',
view=views.SimpleUserViewSet,
name='user-detail'
),
url(