Yakova commited on
Commit
1c349e4
·
verified ·
1 Parent(s): 554f108

Update App/routers/stocks/models.py

Browse files
Files changed (1) hide show
  1. App/routers/stocks/models.py +41 -68
App/routers/stocks/models.py CHANGED
@@ -1,58 +1,28 @@
1
- from tortoise.contrib.pydantic.creator import pydantic_queryset_creator
 
 
2
  from tortoise.models import Model
3
  from tortoise import fields
4
- from tortoise.contrib.pydantic import pydantic_model_creator
5
  from tortoise.queryset import QuerySet
6
 
 
 
 
7
 
8
  class Stock(Model):
9
  id = fields.IntField(primary_key=True)
10
  symbol = fields.CharField(max_length=10, unique=True)
11
  name = fields.CharField(max_length=200)
12
  created_at = fields.DatetimeField(auto_now_add=True)
13
- updated_at = fields.DatetimeField(auto_now=True)
14
-
15
- @staticmethod
16
- async def get_list(data):
17
- if type(data) == list(Stock):
18
- parser = pydantic_queryset_creator(Stock)
19
- return await parser.from_queryset(data)
20
-
21
- async def to_dict(self):
22
- if type(self) == Stock:
23
- parser = pydantic_model_creator(Stock)
24
- return await parser.from_tortoise_orm(self)
25
 
26
  class Meta:
27
  table = "stocks"
28
 
29
 
30
-
31
- # ----------------- STEP 1: Create the SLIM Pydantic model for Stock -----------------
32
- # This model represents a Stock but without its own nested lists.
33
- StockPydantic_Slim = pydantic_model_creator(
34
- Stock,
35
- name="StockSlim",
36
- exclude=("dividends", "portfolio_holdings", "price_data", "watching") # Exclude all reverse relations
37
- )
38
-
39
- # ----------------- STEP 2: Create the FINAL Pydantic model for StockPriceData -----------------
40
- # First, generate a base model from the ORM, excluding the default 'stock' relation
41
- StockPriceData_Pydantic_Base = pydantic_model_creator(
42
- StockPriceData,
43
- name="StockPriceDataBase",
44
- exclude=("stock",)
45
- )
46
-
47
- # Then, create a new class that inherits from the base and adds the 'stock' field back,
48
- # but this time, its type is our new 'StockPydantic_Slim'.
49
- class StockPriceData_Pydantic_Final(StockPriceData_Pydantic_Base):
50
- stock: StockPydantic_Slim
51
-
52
- # ----------------- STEP 3: Update the StockPriceData ORM model -----------------
53
  class StockPriceData(Model):
54
  id = fields.IntField(primary_key=True)
55
- stock = fields.ForeignKeyField("models.Stock", related_name="price_data")
56
  date = fields.DateField()
57
  opening_price = fields.DecimalField(max_digits=15, decimal_places=2)
58
  closing_price = fields.DecimalField(max_digits=15, decimal_places=2)
@@ -67,28 +37,51 @@ class StockPriceData(Model):
67
  @staticmethod
68
  async def get_list(data: QuerySet):
69
  """
70
- Creates a Pydantic model for a list of StockPriceData objects.
71
- This method now correctly uses our custom final Pydantic model to serialize each item.
72
  """
73
- # Create a list/queryset serializer using our final, correctly nested Pydantic model
74
- PriceDataListPydantic = pydantic_queryset_creator(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  tortoise_model=StockPriceData,
76
- pydantic_model=StockPriceData_Pydantic_Final, # This is the key change
77
  name="PriceDataList"
78
  )
79
- return await PriceDataListPydantic.from_queryset(data)
 
 
80
 
81
  async def to_dict(self):
82
- # This method is for single instances, not lists. It can stay as is.
83
  parser = pydantic_model_creator(StockPriceData)
84
  return await parser.from_tortoise_orm(self)
85
 
86
  class Meta:
87
  table = "stock_price_data"
88
  unique_together = (("stock", "date"),)
 
 
89
  class Dividend(Model):
90
  id = fields.IntField(primary_key=True)
91
- stock = fields.ForeignKeyField("models.Stock", related_name="dividends")
92
  ex_dividend_date = fields.DateField()
93
  dividend_amount = fields.DecimalField(max_digits=15, decimal_places=4)
94
  dividend_type = fields.CharField(max_length=50, null=True, blank=True)
@@ -97,28 +90,8 @@ class Dividend(Model):
97
  max_digits=10, decimal_places=4, null=True, blank=True
98
  )
99
  created_at = fields.DatetimeField(auto_now_add=True)
100
- updated_at = fields.DatetimeField(auto_now=True)
101
-
102
- @staticmethod
103
- async def get_list(data):
104
- if type(data) == QuerySet:
105
- parser = pydantic_queryset_creator(Dividend)
106
- return await parser.from_queryset(data)
107
-
108
- async def to_dict(self):
109
- if type(self) == Model:
110
- parser = pydantic_model_creator(Dividend)
111
- return await parser.from_tortoise_orm(self)
112
- if type(self) == QuerySet:
113
- parser = pydantic_queryset_creator(Dividend)
114
- return await parser.from_queryset(self)
115
 
116
  class Meta:
117
  table = "dividends"
118
- ordering = [
119
- "-ex_dividend_date",
120
- "-payment_date",
121
- ] # Order by dates descending by default
122
-
123
- def __str__(self):
124
- return f"{self.stock.symbol} Dividend: {self.dividend_amount} on {self.ex_dividend_date}"
 
1
+ # App/routers/stocks/models.py
2
+
3
+ from tortoise.contrib.pydantic.creator import pydantic_queryset_creator, pydantic_model_creator
4
  from tortoise.models import Model
5
  from tortoise import fields
 
6
  from tortoise.queryset import QuerySet
7
 
8
+ # ===============================================
9
+ # Step 1: Define all your ORM Models first
10
+ # ===============================================
11
 
12
  class Stock(Model):
13
  id = fields.IntField(primary_key=True)
14
  symbol = fields.CharField(max_length=10, unique=True)
15
  name = fields.CharField(max_length=200)
16
  created_at = fields.DatetimeField(auto_now_add=True)
17
+ updated_at = fields.DateTimeField(auto_now=True)
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  class Meta:
20
  table = "stocks"
21
 
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  class StockPriceData(Model):
24
  id = fields.IntField(primary_key=True)
25
+ stock: fields.ForeignKeyRelation[Stock] = fields.ForeignKeyField("models.Stock", related_name="price_data")
26
  date = fields.DateField()
27
  opening_price = fields.DecimalField(max_digits=15, decimal_places=2)
28
  closing_price = fields.DecimalField(max_digits=15, decimal_places=2)
 
37
  @staticmethod
38
  async def get_list(data: QuerySet):
39
  """
40
+ Creates a Pydantic model for a list of StockPriceData objects,
41
+ ensuring the nested 'stock' object is a "slim" version without further nesting.
42
  """
43
+ # --- Pydantic model definitions are now safely inside the method ---
44
+
45
+ # 1. Define a slim Pydantic model for the nested Stock object
46
+ StockPydantic_Slim = pydantic_model_creator(
47
+ Stock,
48
+ name="StockSlim",
49
+ exclude=("dividends", "portfolio_holdings", "price_data", "watching")
50
+ )
51
+
52
+ # 2. Define a base Pydantic model for StockPriceData, excluding the default 'stock' field
53
+ StockPriceData_Pydantic_Base = pydantic_model_creator(
54
+ StockPriceData,
55
+ name="StockPriceDataBase",
56
+ exclude=("stock",)
57
+ )
58
+
59
+ # 3. Create the final Pydantic model by combining the base and the slim stock model
60
+ class StockPriceData_Pydantic_Final(StockPriceData_Pydantic_Base):
61
+ stock: StockPydantic_Slim
62
+
63
+ # 4. Create the serializer for a list of these final models
64
+ PriceDataList_Serializer = pydantic_queryset_creator(
65
  tortoise_model=StockPriceData,
66
+ pydantic_model=StockPriceData_Pydantic_Final,
67
  name="PriceDataList"
68
  )
69
+
70
+ # Finally, serialize the data using the model we just constructed
71
+ return await PriceDataList_Serializer.from_queryset(data)
72
 
73
  async def to_dict(self):
 
74
  parser = pydantic_model_creator(StockPriceData)
75
  return await parser.from_tortoise_orm(self)
76
 
77
  class Meta:
78
  table = "stock_price_data"
79
  unique_together = (("stock", "date"),)
80
+
81
+
82
  class Dividend(Model):
83
  id = fields.IntField(primary_key=True)
84
+ stock: fields.ForeignKeyRelation[Stock] = fields.ForeignKeyField("models.Stock", related_name="dividends")
85
  ex_dividend_date = fields.DateField()
86
  dividend_amount = fields.DecimalField(max_digits=15, decimal_places=4)
87
  dividend_type = fields.CharField(max_length=50, null=True, blank=True)
 
90
  max_digits=10, decimal_places=4, null=True, blank=True
91
  )
92
  created_at = fields.DatetimeField(auto_now_add=True)
93
+ updated_at = fields.DateTimeField(auto_now=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
  class Meta:
96
  table = "dividends"
97
+ ordering = ["-ex_dividend_date", "-payment_date"]