commit
be076f1550
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="room-group-widget">
|
<div class="room-group-widget">
|
||||||
<group></group>
|
<group></group>
|
||||||
<span>
|
<span>
|
||||||
{{name}} - {{year}}
|
{{name}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
import Group from '@/components/icons/Group.vue';
|
import Group from '@/components/icons/Group.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['name', 'year'],
|
props: ['name'],
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
Group
|
Group
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
fragment SchoolClassParts on SchoolClassNode {
|
fragment SchoolClassParts on SchoolClassNode {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
year
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
Vorname,Nachname,Klassen,Rolle,Email
|
||||||
|
Dwight,Schrute,Scranton Branch,Schüler,dwight@dundermifflin.com
|
||||||
|
Michael,Scott,"Scranton Branch,Stanford Branch",Lehrer,michael@dundermifflin.com
|
||||||
|
Jim,Halpert,Scranton Branch,Schüler,jim@dundermifflin.com
|
||||||
|
Pam,Beasley,Scranton Branch,Schüler,pam@dundermifflin.com
|
||||||
|
Karen,Filippelli,Stanford Branch,Schüler,karen@dundermifflin.com
|
||||||
|
Oscar,Martinez,Scranton Branch,Schüler,oscar@dundermifflin.com
|
||||||
|
Meredith,Palmer,Scranton Branch,Schüler,meredith@dundermifflin.com
|
||||||
|
Ryan,Howard,Scranton Branch,Schüler,ryan@dundermifflin.com
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import csv
|
||||||
|
|
||||||
|
from django.core.management import BaseCommand
|
||||||
|
import os
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
from users.models import User, SchoolClass, Role, UserRole
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
def add_arguments(self, parser):
|
||||||
|
parser.add_argument('csv_file')
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
self.stdout.write('Importing from {}!'.format(options['csv_file']))
|
||||||
|
dir_path = settings.BASE_DIR
|
||||||
|
rel_path = options['csv_file']
|
||||||
|
abs_path = os.path.join(dir_path, rel_path)
|
||||||
|
try:
|
||||||
|
with open(abs_path) as f:
|
||||||
|
reader = csv.DictReader(f)
|
||||||
|
for row in reader:
|
||||||
|
email = row['Email'].lower()
|
||||||
|
school_class_names = [c.strip() for c in row['Klassen'].split(',')]
|
||||||
|
first_name = row['Vorname']
|
||||||
|
last_name = row['Nachname']
|
||||||
|
|
||||||
|
self.stdout.write("Creating user {} {}, {}".format(first_name, last_name, email))
|
||||||
|
|
||||||
|
user, created = User.objects.get_or_create(email=email, username=email)
|
||||||
|
user.first_name = first_name
|
||||||
|
user.last_name = last_name
|
||||||
|
user.save()
|
||||||
|
|
||||||
|
if row['Rolle'] == 'Lehrer':
|
||||||
|
self.stdout.write("Assigning teacher role")
|
||||||
|
teacher = Role.objects.get(key='teacher')
|
||||||
|
UserRole.objects.get_or_create(user=user, role=teacher)
|
||||||
|
|
||||||
|
self.stdout.write("Adding to class(es) {}".format(', '.join(school_class_names)))
|
||||||
|
for school_class_name in school_class_names:
|
||||||
|
school, _ = SchoolClass.objects.get_or_create(name=school_class_name)
|
||||||
|
user.school_classes.add(school)
|
||||||
|
|
||||||
|
self.stdout.write("")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.stdout.write(e)
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
from django.test import TestCase, Client
|
||||||
|
from django.core import management
|
||||||
|
|
||||||
|
from users.models import User, Role
|
||||||
|
|
||||||
|
|
||||||
|
class ImportUsersTestCase(TestCase):
|
||||||
|
def test_import(self):
|
||||||
|
Role.objects.create_default_roles()
|
||||||
|
|
||||||
|
management.call_command('import_users', 'Benutzer.sample.csv')
|
||||||
|
|
||||||
|
self.assertEqual(User.objects.count(), 8)
|
||||||
|
|
||||||
|
michael = User.objects.get(email='michael@dundermifflin.com')
|
||||||
|
self.assertEqual(michael.first_name, 'Michael')
|
||||||
|
self.assertEqual(michael.school_classes.count(), 2)
|
||||||
|
self.assertTrue(michael.has_perm('users.can_manage_school_class_content'))
|
||||||
|
|
@ -15,8 +15,7 @@ class RoleInline(admin.TabularInline):
|
||||||
|
|
||||||
@admin.register(SchoolClass)
|
@admin.register(SchoolClass)
|
||||||
class SchoolClassAdmin(admin.ModelAdmin):
|
class SchoolClassAdmin(admin.ModelAdmin):
|
||||||
list_display = ('id', 'name', 'year')
|
list_display = ('id', 'name')
|
||||||
list_filter = ('year',)
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Role)
|
@admin.register(Role)
|
||||||
|
|
@ -37,13 +36,17 @@ class CustomUserAdmin(UserAdmin):
|
||||||
add_form = CustomUserCreationForm
|
add_form = CustomUserCreationForm
|
||||||
form = CustomUserChangeForm
|
form = CustomUserChangeForm
|
||||||
model = User
|
model = User
|
||||||
list_display = ('username', 'first_name', 'last_name',)
|
list_display = ('username', 'first_name', 'last_name', 'school_classes_list')
|
||||||
|
list_filter = ('school_classes',)
|
||||||
|
|
||||||
inlines = [
|
inlines = [
|
||||||
SchoolClassInline,
|
SchoolClassInline,
|
||||||
RoleInline,
|
RoleInline,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def school_classes_list(self, obj):
|
||||||
|
return ', '.join([s.name for s in obj.school_classes.all()])
|
||||||
|
|
||||||
# fieldsets = UserAdmin.fieldsets + (
|
# fieldsets = UserAdmin.fieldsets + (
|
||||||
# (None, {'fields': ('school_classes',)}),
|
# (None, {'fields': ('school_classes',)}),
|
||||||
# )
|
# )
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ class SchoolClassFactory(factory.django.DjangoModelFactory):
|
||||||
model = SchoolClass
|
model = SchoolClass
|
||||||
|
|
||||||
name = factory.Sequence(lambda n: '{}{}{}'.format(random.choice(class_types), '18', class_suffix[n % len(class_suffix)]))
|
name = factory.Sequence(lambda n: '{}{}{}'.format(random.choice(class_types), '18', class_suffix[n % len(class_suffix)]))
|
||||||
year = factory.LazyAttribute(lambda x: random.choice([2017, 2018, 2019]))
|
|
||||||
is_deleted = False
|
is_deleted = False
|
||||||
|
|
||||||
@factory.post_generation
|
@factory.post_generation
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ from graphene import InputObjectType
|
||||||
class SchoolClassInput(InputObjectType):
|
class SchoolClassInput(InputObjectType):
|
||||||
id = graphene.ID()
|
id = graphene.ID()
|
||||||
name = graphene.String()
|
name = graphene.String()
|
||||||
year = graphene.Int()
|
|
||||||
|
|
||||||
|
|
||||||
class PasswordUpdateInput(InputObjectType):
|
class PasswordUpdateInput(InputObjectType):
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Generated by Django 2.0.6 on 2019-07-03 09:55
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('users', '0004_user_avatar_url'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='schoolclass',
|
||||||
|
name='year',
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='user',
|
||||||
|
name='email',
|
||||||
|
field=models.EmailField(max_length=254, unique=True, verbose_name='email address'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.0.6 on 2019-07-03 09:59
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('users', '0005_auto_20190703_0955'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='schoolclass',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=100, unique=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -13,6 +13,7 @@ DEFAULT_SCHOOL_ID = 1
|
||||||
class User(AbstractUser):
|
class User(AbstractUser):
|
||||||
last_module = models.ForeignKey('books.Module', related_name='+', on_delete=models.SET_NULL, null=True)
|
last_module = models.ForeignKey('books.Module', related_name='+', on_delete=models.SET_NULL, null=True)
|
||||||
avatar_url = models.CharField(max_length=254, blank=True, default='')
|
avatar_url = models.CharField(max_length=254, blank=True, default='')
|
||||||
|
email = models.EmailField(_('email address'), unique=True)
|
||||||
|
|
||||||
def get_role_permissions(self):
|
def get_role_permissions(self):
|
||||||
perms = set()
|
perms = set()
|
||||||
|
|
@ -43,14 +44,12 @@ class User(AbstractUser):
|
||||||
|
|
||||||
|
|
||||||
class SchoolClass(models.Model):
|
class SchoolClass(models.Model):
|
||||||
name = models.CharField(max_length=100, blank=False, null=False)
|
name = models.CharField(max_length=100, blank=False, null=False, unique=True)
|
||||||
year = models.PositiveIntegerField(blank=False, null=False,
|
|
||||||
validators=[MinValueValidator(1900), MaxValueValidator(2200)])
|
|
||||||
is_deleted = models.BooleanField(blank=False, null=False, default=False)
|
is_deleted = models.BooleanField(blank=False, null=False, default=False)
|
||||||
users = models.ManyToManyField(get_user_model(), related_name='school_classes')
|
users = models.ManyToManyField(get_user_model(), related_name='school_classes')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'SchoolClass {}-{}-{}'.format(self.id, self.name, self.year)
|
return 'SchoolClass {}-{}'.format(self.id, self.name)
|
||||||
|
|
||||||
def is_user_in_schoolclass(self, user):
|
def is_user_in_schoolclass(self, user):
|
||||||
return user.is_superuser or user.school_classes.filter(pk=self.id).count() > 0
|
return user.is_superuser or user.school_classes.filter(pk=self.id).count() > 0
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ def create_users(data=None):
|
||||||
|
|
||||||
SchoolClassFactory(
|
SchoolClassFactory(
|
||||||
users=[teacher] + students,
|
users=[teacher] + students,
|
||||||
year='2018',
|
|
||||||
name='skillbox'
|
name='skillbox'
|
||||||
)
|
)
|
||||||
teacher2 = UserFactory(username='teacher2')
|
teacher2 = UserFactory(username='teacher2')
|
||||||
|
|
@ -30,7 +29,6 @@ def create_users(data=None):
|
||||||
UserRole.objects.create(user=student_second_class, role=student_role)
|
UserRole.objects.create(user=student_second_class, role=student_role)
|
||||||
SchoolClassFactory(
|
SchoolClassFactory(
|
||||||
users=[teacher2, student_second_class],
|
users=[teacher2, student_second_class],
|
||||||
year='2018',
|
|
||||||
name='second_class'
|
name='second_class'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -59,5 +57,4 @@ def create_users(data=None):
|
||||||
SchoolClassFactory(
|
SchoolClassFactory(
|
||||||
users=students + [teacher],
|
users=students + [teacher],
|
||||||
name=school_class.get('class'),
|
name=school_class.get('class'),
|
||||||
year='2018'
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue