Skip to content

Commit

Permalink
Migrate Passenger model to User model (solves #308) (#350)
Browse files Browse the repository at this point in the history
  • Loading branch information
ngiersz authored and magul committed Oct 23, 2019
1 parent 06b9f49 commit 7aeaaca
Show file tree
Hide file tree
Showing 14 changed files with 174 additions and 109 deletions.
9 changes: 4 additions & 5 deletions backend/fleet_management/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
from import_export.admin import ImportExportModelAdmin
from import_export.fields import Field
from import_export import resources
from .models import Car, Passenger, Drive, User, Project
from .models import Car, Drive, User, Project


class DriveResource(resources.ModelResource):
def dehydrate_passengers(self, drive):
return " / ".join(str(passenger) for passenger in drive.passengers.all())
def dehydrate_passenger(self, drive):
return str(drive.passenger)

def dehydrate_driver(self, drive):
return str(drive.driver) # required, because import-export prints PK by default
Expand All @@ -23,7 +23,7 @@ class Meta:
model = Drive
fields = (
"id",
"passengers",
"passenger",
"date",
"start_mileage",
"end_mileage",
Expand Down Expand Up @@ -68,7 +68,6 @@ class CustomUserAdmin(UserAdmin):


admin.site.register(Car)
admin.site.register(Passenger)
admin.site.register(Drive, DriveAdmin)
admin.site.register(User, CustomUserAdmin)
admin.site.register(Project)
9 changes: 5 additions & 4 deletions backend/fleet_management/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
from rest_framework.response import Response

from .permissions import GroupPermission, all_driver_methods
from .models import Car, Drive, Passenger, Project
from .models import User, Car, Drive, Project
from .serializers import (
CarSerializer,
DriveSerializer,
PassengerSerializer,
UserSerializer,
ProjectSerializer,
)

from .constants import Groups

class CurrentUserRetrieveView(views.APIView):

Expand All @@ -32,9 +32,10 @@ class PassengerListView(generics.ListAPIView):
ordering = ('first_name', 'last_name')

def get_queryset(self):
return Passenger.objects.filter(
return User.objects.filter(
groups__name=Groups.Passenger.name,
country=self.request.user.country
) | Passenger.objects.filter(country=None)
) | User.objects.filter(country=None, groups__name=Groups.Passenger.name)


class CarListView(generics.ListAPIView):
Expand Down
27 changes: 7 additions & 20 deletions backend/fleet_management/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


from fleet_management.models import (
Car, Drive, Passenger, Project, User
Car, Drive, Project, User
)

COUNTRIES = ('UA', 'SS')
Expand All @@ -31,7 +31,11 @@ class Meta:
@classmethod
def _create(cls, model_class, *args, **kwargs):
manager = cls._get_manager(model_class)
return manager.create_user(*args, **kwargs)
groups = kwargs.pop("groups", [])
user = manager.create_user(*args, **kwargs)
for g in groups:
user.groups.add(g)
return user


class CarFactory(DjangoModelFactory):
Expand Down Expand Up @@ -111,16 +115,6 @@ def description(self):
)


class PassengerFactory(DjangoModelFactory):

class Meta:
model = Passenger

first_name = Faker('first_name', locale='pl_PL')
last_name = Faker('last_name', locale='pl_PL')
country = fuzzy.FuzzyChoice(COUNTRIES)


class ProjectFactory(DjangoModelFactory):

class Meta:
Expand All @@ -147,6 +141,7 @@ class Meta:

driver = SubFactory(UserFactory)
project = SubFactory(ProjectFactory)
passenger = SubFactory(UserFactory)
car = SubFactory(CarFactory)
date = fuzzy.FuzzyDate((now() - timedelta(days=1000)).date())
start_mileage = fuzzy.FuzzyInteger(1000000)
Expand All @@ -160,11 +155,3 @@ class Meta:
def end_mileage(self):
return random.randint(self.start_mileage, 1000000)

@post_generation
def passengers(self, create, extracted, **kwargs):
if not create:
return

if extracted:
for passenger in extracted:
self.passengers.add(passenger)
36 changes: 22 additions & 14 deletions backend/fleet_management/management/commands/populate_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@
from fleet_management.factories import (
CarFactory,
DriveFactory,
PassengerFactory,
ProjectFactory,
UserFactory,
)
from ...models import Passenger, Project, User
from ...models import Project, User


class Command(BaseCommand):
Expand All @@ -23,50 +22,59 @@ class Command(BaseCommand):
help = "Populates database with fake items."

def handle(self, *args, **options):
driver_group = Group.objects.get(name=Groups.Driver.name)
passenger_group = Group.objects.get(name=Groups.Passenger.name)

self.stdout.write(self.style.SUCCESS('Creating 5 cars'))
for _ in tqdm(range(5)):
CarFactory.create()

self.stdout.write(self.style.SUCCESS('Creating 5 users'))
usernames = []
self.stdout.write(self.style.SUCCESS('Creating 5 drivers'))
drivers = []
for _ in tqdm(range(5)):
usernames.append(UserFactory.create().username)
drivers.append(UserFactory.create(groups=[driver_group]).username)

passengers = []
self.stdout.write(self.style.SUCCESS('Creating 10 passengers'))
for _ in tqdm(range(10)):
PassengerFactory.create()
passengers.append(UserFactory.create(groups=[passenger_group]).username)

self.stdout.write(self.style.SUCCESS('Creating 5 projects'))
for _ in tqdm(range(5)):
ProjectFactory.create()

self.stdout.write(self.style.SUCCESS('Creating 50 drives'))
all_users = list(User.objects.all())
all_passengers = list(Passenger.objects.all())
all_drivers = list(User.objects.filter(groups=driver_group))
all_passengers = list(User.objects.filter(groups=passenger_group))
all_projects = list(Project.objects.all())

for _ in tqdm(range(50)):
DriveFactory.create(
passengers=random.sample(all_passengers, random.randint(1, 4)),
passenger=random.choice(all_passengers),
project=random.choice(all_projects),
driver=random.choice(all_users),
driver=random.choice(all_drivers),
)

self.stdout.write(
self.style.SUCCESS('Database successfully populated')
)

self.stdout.write('=' * 50)
self.stdout.write(self.style.SUCCESS('Newly created users:'))
for index, username in enumerate(usernames):
self.stdout.write(self.style.SUCCESS('Newly created drivers:'))
for index, username in enumerate(drivers):
self.stdout.write(self.style.SUCCESS('{index}. {username}'.format(
index=index,
username=username,
)))

self.stdout.write(self.style.SUCCESS('Newly created passengers:'))
for index, username in enumerate(passengers):
self.stdout.write(self.style.SUCCESS('{index}. {username}'.format(
index=index,
username=username,
)))

default_user = User.objects.filter(email='[email protected]').first()

driver_group = Group.objects.get(name=Groups.Driver.name)
driver_group.user_set.add(default_user)
passenger_group = Group.objects.get(name=Groups.Passenger.name)
passenger_group.user_set.add(default_user)
17 changes: 8 additions & 9 deletions backend/fleet_management/migrations/0011_add_default_groups.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@

from django.db import migrations, connections
from django.contrib.auth.models import Group
from ..models import User


from ..constants import Groups
from django.db import migrations


def create_groups(apps, schema_editor):
Group.objects.create(name=Groups.Passenger.name)
Group.objects.create(name=Groups.Driver.name)
Group = apps.get_model("auth", "Group")

Group.objects.create(name="Passenger")
Group.objects.create(name="Driver")


def insert_to_groups(apps, schema_editor):
g = Group.objects.get(name=Groups.Driver.name)
User = apps.get_model("fleet_management", "User")
Group = apps.get_model("auth", "Group")
g = Group.objects.get(name="Driver")
users = User.objects.all()
for u in users:
g.user_set.add(u)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

from django.db import migrations, models

from ..models import Drive


def default_is_verified(apps, schema_editor):
Drive = apps.get_model("fleet_management", "Drive")
drives = Drive.objects.all()
for drive in drives:
drive.is_verified = True
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from django.db import migrations
from ..models import Project


def default_country_to_project(apps, schema_editor):
Project = apps.get_model("fleet_management", "Project")
projects = Project.objects.all()
for project in projects:
project.country = 'UA'
Expand Down
31 changes: 31 additions & 0 deletions backend/fleet_management/migrations/0017_auto_20191002_1858.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 2.1.2 on 2019-10-02 18:58

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django_countries.fields


class Migration(migrations.Migration):

dependencies = [
('fleet_management', '0016_auto_20190825_2051'),
]

operations = [
migrations.AddField(
model_name='drive',
name='passenger',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='drives_taken', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='drive',
name='driver',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='drives_driven', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='project',
name='country',
field=django_countries.fields.CountryField(default=None, max_length=2),
),
]
44 changes: 44 additions & 0 deletions backend/fleet_management/migrations/0018_passenger_to_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Generated by Django 2.1.2 on 2019-10-02 19:00

from django.db import migrations


def migrate_passenger_to_user(apps, schema_editor):
Passenger = apps.get_model("fleet_management", "Passenger")
User = apps.get_model("fleet_management", "User")
Group = apps.get_model("auth", "Group")
Drive = apps.get_model("fleet_management", "Drive")
g = Group.objects.get(name="Passenger")
passengers = Passenger.objects.all()
for p in passengers:
u, created = User.objects.get_or_create(
username=p.email,
defaults={
'email': p.email,
'is_superuser': False,
'is_staff': False,
'country': p.country,
'is_active': True,
'first_name': p.first_name,
'last_name': p.last_name
}
)
u.save()
g.user_set.add(u)

drives = Drive.objects.filter(passengers=p.id)
for d in drives:
assert d.passengers.all().count() == 1, f"Too many passengers in a drive {d.id}"
d.passenger = u
d.save()


class Migration(migrations.Migration):

dependencies = [
('fleet_management', '0017_auto_20191002_1858'),
]

operations = [
migrations.RunPython(migrate_passenger_to_user),
]
20 changes: 20 additions & 0 deletions backend/fleet_management/migrations/0019_remove_passenger_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 2.1.2 on 2019-10-02 21:00

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('fleet_management', '0018_passenger_to_user'),
]

operations = [
migrations.RemoveField(
model_name='drive',
name='passengers',
),
migrations.DeleteModel(
name='Passenger',
),
]
14 changes: 2 additions & 12 deletions backend/fleet_management/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,6 @@ def __str__(self):
return self.plates


class Passenger(models.Model):
first_name = models.CharField(max_length=60, blank=False)
last_name = models.CharField(max_length=60, blank=False)
email = models.EmailField(blank=False)
country = CountryField(blank_label='(select country)', null=True, default=None)

def __str__(self):
return f"{self.first_name} {self.last_name}"


class Project(models.Model):
title = models.CharField(max_length=50, blank=False)
description = models.CharField(max_length=1000, blank=False)
Expand All @@ -48,9 +38,8 @@ def __str__(self):


class Drive(models.Model):
driver = models.ForeignKey(User, on_delete=models.CASCADE)
driver = models.ForeignKey(User, on_delete=models.CASCADE, related_name="drives_driven")
car = models.ForeignKey(Car, null=False, on_delete=models.CASCADE)
passengers = models.ManyToManyField(Passenger)
date = models.DateField(default=now, blank=False)
start_mileage = models.IntegerField(null=False)
end_mileage = models.IntegerField(null=False)
Expand All @@ -60,6 +49,7 @@ class Drive(models.Model):
timestamp = models.IntegerField(blank=False, default=get_current_timestamp_in_gmt)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
is_verified = models.BooleanField(default=False)
passenger = models.ForeignKey(User, on_delete=models.CASCADE, related_name="drives_taken", null=True, blank=True)

class Meta:
unique_together = [
Expand Down
Loading

0 comments on commit 7aeaaca

Please sign in to comment.