Skip to content

Commit

Permalink
chore(django_example): improve example with multi database setting
Browse files Browse the repository at this point in the history
  • Loading branch information
jbarreau committed Nov 28, 2023
1 parent 8ebc2bd commit dbb12a6
Show file tree
Hide file tree
Showing 8 changed files with 1,171 additions and 16 deletions.
764 changes: 763 additions & 1 deletion src/_example/django/django_demo/.forestadmin-schema.json

Large diffs are not rendered by default.

79 changes: 79 additions & 0 deletions src/_example/django/django_demo/app/flask_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior
# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
from django.db import models


class FlaskAddress(models.Model):
id = models.AutoField(primary_key=True, db_column="pk")
street = models.CharField(max_length=255)
street_number = models.CharField(max_length=2, blank=True, null=True)
city = models.CharField(max_length=255)
country = models.CharField(max_length=255)
zip_code = models.CharField(max_length=5)
# customers = models.ManyToManyField("FlaskCustomer", through="FlaskCustomersAddresses")

class Meta:
# managed = False
db_table = "address"


class FlaskCustomer(models.Model):
id = models.BinaryField(primary_key=True, db_column="pk")
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
birthday_date = models.DateTimeField(blank=True, null=True)
age = models.IntegerField(blank=True, null=True)
is_vip = models.BooleanField(blank=True, null=True)
avatar = models.BinaryField(blank=True, null=True)
addresses = models.ManyToManyField("FlaskAddress", through="FlaskCustomersAddresses", related_name="customers")

class Meta:
# managed = False
db_table = "customer"


class FlaskCustomersAddresses(models.Model):
customer = models.ForeignKey(FlaskCustomer, models.DO_NOTHING)
address = models.ForeignKey(FlaskAddress, models.DO_NOTHING)

class Meta:
# managed = False
db_table = "customers_addresses"


class FlaskOrder(models.Model):
class OrderStatus(models.TextChoices):
PENDING = ("PENDING", "Pending")
DISPATCHED = ("DISPATCHED", "Dispatched")
DELIVERED = ("DELIVERED", "Delivered")
REJECTED = ("REJECTED", "Rejected")

id = models.AutoField(primary_key=True, db_column="pk")
created_at = models.DateTimeField(blank=True, null=True)
amount = models.IntegerField()
customer = models.ForeignKey(FlaskCustomer, models.DO_NOTHING, blank=True, null=True)
billing_address = models.ForeignKey(FlaskAddress, models.DO_NOTHING, blank=True, null=True)
delivering_address = models.ForeignKey(
FlaskAddress, models.DO_NOTHING, related_name="order_delivering_address_set", blank=True, null=True
)
status = models.CharField(max_length=10, choices=OrderStatus.choices)

class Meta:
# managed = False
db_table = "order"


class FlaskCart(models.Model):
id = models.AutoField(primary_key=True, db_column="pk")
name = models.CharField(max_length=255)
created_at = models.DateTimeField(blank=True, null=True)
order = models.ForeignKey("FlaskOrder", models.DO_NOTHING, blank=True, null=True)

class Meta:
# managed = False
db_table = "cart"
113 changes: 100 additions & 13 deletions src/_example/django/django_demo/app/management/commands/populate-db.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import random
from datetime import datetime, timezone
from uuid import uuid4

from app.flask_models import FlaskAddress, FlaskCart, FlaskCustomer, FlaskCustomersAddresses, FlaskOrder
from app.models import Address, Cart, Customer, CustomerAddress, Order
from django.contrib.auth.models import Group, User
from django.core.management.base import BaseCommand
Expand All @@ -19,6 +21,17 @@ def add_arguments(self, parser):
help=f"create a lot of data, can take a while(~=5min)). Open this file ({__file__}) to edit the values",
action="store_true",
)
parser.add_argument(
"-o",
"--only-other-database",
help="only populate 'other' database",
action="store_true",
)
parser.add_argument(
"--only-default-database",
help="don't populate 'other' database",
action="store_true",
)

def handle(self, *args, **options):
numbers = {
Expand All @@ -37,21 +50,30 @@ def handle(self, *args, **options):
"orders_carts": 3000000,
}

users, groups = create_users_groups(numbers["groups"], numbers["users"])
if options["verbosity"] != 0:
print(f"users({numbers['users']}) and groups({numbers['groups']}) created ")
if options["only_default_database"] or not options["only_other_database"]:
users, groups = create_users_groups(numbers["groups"], numbers["users"])
if options["verbosity"] != 0:
print(f"users({numbers['users']}) and groups({numbers['groups']}) created ")

customers = create_customers(numbers["customers"])
if options["verbosity"] != 0:
print(f"customers({numbers['customers']}) created")
customers = create_customers(numbers["customers"])
if options["verbosity"] != 0:
print(f"customers({numbers['customers']}) created")

addresses = create_addresses(customers, numbers["addresses"])
if options["verbosity"] != 0:
print(f"addresses({numbers['addresses']}) created")
addresses = create_addresses(customers, numbers["addresses"])
if options["verbosity"] != 0:
print(f"addresses({numbers['addresses']}) created")

orders, carts = create_orders_cart(customers, addresses, numbers["orders_carts"])
if options["verbosity"] != 0:
print(f"orders and carts ({numbers['orders_carts']}) created")
orders, carts = create_orders_cart(customers, addresses, numbers["orders_carts"])
if options["verbosity"] != 0:
print(f"orders and carts ({numbers['orders_carts']}) created")

if not options["only_default_database"] or options["only_other_database"]:
customers = populate_flask_customers(numbers["customers"])
addresses = populate_flask_addresses(customers)
populate_orders(addresses)


# main db


def create_users_groups(nb_group=4, nb_users=10):
Expand Down Expand Up @@ -85,7 +107,11 @@ def create_users_groups(nb_group=4, nb_users=10):
def create_customers(nb_customers=500):
customers = []
for i in range(nb_customers):
c = Customer(first_name=fake.first_name(), last_name=fake.last_name(), birthday_date=fake.date_of_birth())
c = Customer(
first_name=fake.first_name(),
last_name=fake.last_name(),
birthday_date=fake.date_of_birth(tzinfo=timezone.utc),
)
customers.append(c)
Customer.objects.bulk_create(customers)
customers = Customer.objects.all()
Expand Down Expand Up @@ -139,3 +165,64 @@ def create_orders_cart(customers, addresses, nb_order=1000):
Cart.objects.bulk_create(carts)
carts = Cart.objects.all()
return orders, carts


# other db


def populate_flask_customers(nb: int = 500):
FlaskCustomer.objects.bulk_create(
[
FlaskCustomer(
id=str(uuid4()).encode("utf-8"),
first_name=fake.first_name(),
last_name=fake.last_name(),
birthday_date=datetime.fromordinal(fake.date_of_birth().toordinal()).replace(tzinfo=timezone.utc),
age=random.choices([None, random.randint(16, 120)])[0],
is_vip=random.choice([True, False]),
)
for i in range(nb)
],
)
return FlaskCustomer.objects.all()


def populate_flask_addresses(customers):
addresses = []
for _ in range(0, customers.count() * 2):
address = FlaskAddress(
street=fake.street_address(), city=fake.city(), country=fake.country(), zip_code=fake.postcode()
)
addresses.append(address)
FlaskAddress.objects.bulk_create(addresses)
addresses = FlaskAddress.objects.all()

customers_addresses = []
for address in addresses:
known_customer = set()
for _ in range(1, random.randint(2, 4)):
customer = random.choices(customers)[0]
if customer not in known_customer:
known_customer.add(customer)
customers_addresses.append(FlaskCustomersAddresses(address=address, customer=customer))
FlaskCustomersAddresses.objects.bulk_create(customers_addresses)
return addresses


def populate_orders(addresses):
orders = []
for address in addresses:
o = FlaskOrder(
amount=random.randint(10, 10000),
created_at=fake.date_time_between_dates(datetime(2021, 1, 1), datetime.utcnow(), tzinfo=timezone.utc),
customer=address.customers.all()[0],
billing_address=address,
delivering_address=address,
status=random.choice(list(FlaskOrder.OrderStatus)),
)
orders.append(o)
FlaskOrder.objects.bulk_create(orders)
FlaskCart.objects.bulk_create(
[FlaskCart(name=fake.language_name(), order_id=order.pk) for order in FlaskOrder.objects.all()]
)
return orders
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# Generated by Django 4.2.7 on 2023-11-28 15:12

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
("app", "0001_initial"),
]

operations = [
migrations.CreateModel(
name="FlaskAddress",
fields=[
(
"id",
models.AutoField(db_column="pk", primary_key=True, serialize=False),
),
("street", models.CharField(max_length=255)),
(
"street_number",
models.CharField(blank=True, max_length=2, null=True),
),
("city", models.CharField(max_length=255)),
("country", models.CharField(max_length=255)),
("zip_code", models.CharField(max_length=5)),
],
options={
"db_table": "address",
},
),
migrations.CreateModel(
name="FlaskCustomer",
fields=[
(
"id",
models.BinaryField(
db_column="pk", primary_key=True, serialize=False
),
),
("first_name", models.CharField(max_length=255)),
("last_name", models.CharField(max_length=255)),
("birthday_date", models.DateTimeField(blank=True, null=True)),
("age", models.IntegerField(blank=True, null=True)),
("is_vip", models.BooleanField(blank=True, null=True)),
("avatar", models.BinaryField(blank=True, null=True)),
],
options={
"db_table": "customer",
},
),
migrations.CreateModel(
name="FlaskOrder",
fields=[
(
"id",
models.AutoField(db_column="pk", primary_key=True, serialize=False),
),
("created_at", models.DateTimeField(blank=True, null=True)),
("amount", models.IntegerField()),
(
"status",
models.CharField(
choices=[
("PENDING", "Pending"),
("DISPATCHED", "Dispatched"),
("DELIVERED", "Delivered"),
("REJECTED", "Rejected"),
],
max_length=10,
),
),
(
"billing_address",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
to="app.flaskaddress",
),
),
(
"customer",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
to="app.flaskcustomer",
),
),
(
"delivering_address",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="order_delivering_address_set",
to="app.flaskaddress",
),
),
],
options={
"db_table": "order",
},
),
migrations.CreateModel(
name="FlaskCustomersAddresses",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"address",
models.ForeignKey(
on_delete=django.db.models.deletion.DO_NOTHING,
to="app.flaskaddress",
),
),
(
"customer",
models.ForeignKey(
on_delete=django.db.models.deletion.DO_NOTHING,
to="app.flaskcustomer",
),
),
],
options={
"db_table": "customers_addresses",
},
),
migrations.AddField(
model_name="flaskcustomer",
name="addresses",
field=models.ManyToManyField(
related_name="customers",
through="app.FlaskCustomersAddresses",
to="app.flaskaddress",
),
),
migrations.CreateModel(
name="FlaskCart",
fields=[
(
"id",
models.AutoField(db_column="pk", primary_key=True, serialize=False),
),
("name", models.CharField(max_length=255)),
("created_at", models.DateTimeField(blank=True, null=True)),
(
"order",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
to="app.flaskorder",
),
),
],
options={
"db_table": "cart",
},
),
]
Loading

0 comments on commit dbb12a6

Please sign in to comment.