Repository: asyncapi/modelina (ts)

Issue:
[BUG] missing default value in Pydantic generated code when using polymorphism
### Describe the bug.

From Vehicle schema example code generated for python with Pydantic is missing default values for discriminator field, which demolishes the idea of simple usage.

Example schema:
```yaml
asyncapi: 3.0.0
info:
  title: Vehicle Models
  version: 1.0.0
components:
  messages:
    Vehicle:
      payload:
        oneOf:
          - $ref: '#/components/schemas/Car'
          - $ref: '#/components/schemas/Truck'
  schemas:
    Vehicle:
      title: Vehicle
      type: object
      discriminator: vehicleType
      properties:
        vehicleType:
          title: VehicleType
          type: string
        length:
          type: number
          format: float
      required:
        - vehicleType
    Car:
      allOf:
        - $ref: '#/components/schemas/Vehicle'
        - type: object
          properties:
            vehicleType:
              const: Car
    Truck:
      allOf:
        - $ref: '#/components/schemas/Vehicle'
        - type: object
          properties:
            vehicleType:
              const: Truck
```

which generates following with std python:
```python
class Car: 
  def __init__(self, input: Dict):
    self._vehicle_type: VehicleType.VehicleType = VehicleType.VehicleType.CAR
    if 'length' in input:
      self._length: float = input['length']
    if 'additional_properties' in input:
      self._additional_properties: dict[str, Any] = input['additional_properties']
```
but with Pydantic:
```python
class Car(BaseModel): 
  vehicle_type: VehicleType.VehicleType = Field()
  length: Optional[float] = Field(default=None)
  additional_properties: Optional[dict[str, Any]] = Field(default=None, exclude=True)
```


### Expected behavior

expected code to be generated is:
```python
class Car(BaseModel): 
  vehicle_type: VehicleType.VehicleType = Field(default=VehicleType.VehicleType.CAR)
  length: Optional[float] = Field(default=None)
  additional_properties: Optional[dict[str, Any]] = Field(default=None, exclude=True)
```

### Screenshots

none

### How to Reproduce

1. generate code from given schema for std python
2. generate code from given schema for python using Pydantic
3. compare the results, find the missing `default`


### 🖥️ Device Information [optional]

- Operating System (OS): Ubuntu 24.04
- Browser: not relevant
- Browser Version: not relevant


### 👀 Have you checked for similar open issues?

- [x] I checked and didn't find similar issue

### 🏢 Have you read the Contributing Guidelines?

- [x] I have read the [Contributing Guidelines](https://github.com/asyncapi/.github/blob/master/CONTRIBUTING.md)

### Are you willing to work on this issue ?

Yes I am willing to submit a PR!

Pull request:
fix: missing default value in Pydantic generated code when using polymorphism
## Description
Code generated for python with Pydantic is missing default values for discriminator field, when polymorphism is used with discriminator assigned via const. This PR adds `default` value to field and sets the field as `frozen`.

## Related Issue
Resolves #2270 

## Checklist
- [X] The code follows the project's coding standards and is properly linted (`npm run lint`).
- [X] Tests have been added or updated to cover the changes.
- [ ] Documentation has been updated to reflect the changes.
- [X] All tests pass successfully locally.(`npm run test`).

## Additional Notes
--- 


Patch:
diff --git a/src/generators/python/presets/Pydantic.ts b/src/generators/python/presets/Pydantic.ts
index d4d1931d..a4ff36d6 100644
--- a/src/generators/python/presets/Pydantic.ts
+++ b/src/generators/python/presets/Pydantic.ts
@@ -53,6 +53,10 @@ const PYTHON_PYDANTIC_CLASS_PRESET: ClassPresetType<PythonOptions> = {
     if (isOptional) {
       decoratorArgs.push('default=None');
     }
+    if (property.property.options.const) {
+      decoratorArgs.push(`default=${property.property.options.const.value}`);
+      decoratorArgs.push('frozen=True');
+    }
     if (
       property.property instanceof ConstrainedDictionaryModel &&
       property.property.serializationType === 'unwrap'


Test patch:
diff --git a/test/generators/python/presets/Pydantic.spec.ts b/test/generators/python/presets/Pydantic.spec.ts
index a76f8f93..283ef43d 100644
--- a/test/generators/python/presets/Pydantic.spec.ts
+++ b/test/generators/python/presets/Pydantic.spec.ts
@@ -94,4 +94,73 @@ describe('PYTHON_PYDANTIC_PRESET', () => {
     const models = await generator.generate(doc);
     expect(models.map((model) => model.result)).toMatchSnapshot();
   });
+
+  test('should render default value for discriminator when using polymorphism', async () => {
+    const doc = {
+      asyncapi: '3.0.0',
+      info: {
+        title: 'Vehicle Models',
+        version: '1.0.0'
+      },
+      components: {
+        messages: {
+          Vehicle: {
+            payload: {
+              oneOf: [
+                { $ref: '#/components/schemas/Car' },
+                { $ref: '#/components/schemas/Truck' }
+              ]
+            }
+          }
+        },
+        schemas: {
+          Vehicle: {
+            title: 'Vehicle',
+            type: 'object',
+            discriminator: 'vehicleType',
+            properties: {
+              vehicleType: {
+                title: 'VehicleType',
+                type: 'string'
+              },
+              length: {
+                type: 'number',
+                format: 'float'
+              }
+            },
+            required: ['vehicleType']
+          },
+          Car: {
+            allOf: [
+              { $ref: '#/components/schemas/Vehicle' },
+              {
+                type: 'object',
+                properties: {
+                  vehicleType: {
+                    const: 'Car'
+                  }
+                }
+              }
+            ]
+          },
+          Truck: {
+            allOf: [
+              { $ref: '#/components/schemas/Vehicle' },
+              {
+                type: 'object',
+                properties: {
+                  vehicleType: {
+                    const: 'Truck'
+                  }
+                }
+              }
+            ]
+          }
+        }
+      }
+    };
+
+    const models = await generator.generate(doc);
+    expect(models.map((model) => model.result)).toMatchSnapshot();
+  });
 });
diff --git a/test/generators/python/presets/__snapshots__/Pydantic.spec.ts.snap b/test/generators/python/presets/__snapshots__/Pydantic.spec.ts.snap
index 7135ae1e..635b3591 100644
--- a/test/generators/python/presets/__snapshots__/Pydantic.spec.ts.snap
+++ b/test/generators/python/presets/__snapshots__/Pydantic.spec.ts.snap
@@ -1,5 +1,90 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`PYTHON_PYDANTIC_PRESET should render default value for discriminator when using polymorphism 1`] = `
+Array [
+  "",
+  "class Car(BaseModel): 
+  vehicle_type: VehicleType.VehicleType = Field(default=VehicleType.VehicleType.CAR, frozen=True)
+  length: Optional[float] = Field(default=None)
+  additional_properties: Optional[dict[str, Any]] = Field(default=None, exclude=True)
+
+  @model_serializer(mode='wrap')
+  def custom_serializer(self, handler):
+    serialized_self = handler(self)
+    additional_properties = getattr(self, \\"additional_properties\\")
+    if additional_properties is not None:
+      for key, value in additional_properties.items():
+        # Never overwrite existing values, to avoid clashes
+        if not hasattr(serialized_self, key):
+          serialized_self[key] = value
+
+    return serialized_self
+
+  @model_validator(mode='before')
+  @classmethod
+  def unwrap_additional_properties(cls, data):
+    if not isinstance(data, dict):
+      data = data.model_dump()
+    json_properties = list(data.keys())
+    known_object_properties = ['vehicle_type', 'length', 'additional_properties']
+    unknown_object_properties = [element for element in json_properties if element not in known_object_properties]
+    # Ignore attempts that validate regular models, only when unknown input is used we add unwrap extensions
+    if len(unknown_object_properties) == 0: 
+      return data
+  
+    known_json_properties = ['vehicleType', 'length', 'additionalProperties']
+    additional_properties = data.get('additional_properties', {})
+    for obj_key in list(data.keys()):
+      if not known_json_properties.__contains__(obj_key):
+        additional_properties[obj_key] = data.pop(obj_key, None)
+    data['additional_properties'] = additional_properties
+    return data
+
+",
+  "class VehicleType(Enum): 
+  CAR = \\"Car\\"
+  TRUCK = \\"Truck\\"",
+  "class Truck(BaseModel): 
+  vehicle_type: VehicleType.VehicleType = Field(default=VehicleType.VehicleType.TRUCK, frozen=True)
+  length: Optional[float] = Field(default=None)
+  additional_properties: Optional[dict[str, Any]] = Field(default=None, exclude=True)
+
+  @model_serializer(mode='wrap')
+  def custom_serializer(self, handler):
+    serialized_self = handler(self)
+    additional_properties = getattr(self, \\"additional_properties\\")
+    if additional_properties is not None:
+      for key, value in additional_properties.items():
+        # Never overwrite existing values, to avoid clashes
+        if not hasattr(serialized_self, key):
+          serialized_self[key] = value
+
+    return serialized_self
+
+  @model_validator(mode='before')
+  @classmethod
+  def unwrap_additional_properties(cls, data):
+    if not isinstance(data, dict):
+      data = data.model_dump()
+    json_properties = list(data.keys())
+    known_object_properties = ['vehicle_type', 'length', 'additional_properties']
+    unknown_object_properties = [element for element in json_properties if element not in known_object_properties]
+    # Ignore attempts that validate regular models, only when unknown input is used we add unwrap extensions
+    if len(unknown_object_properties) == 0: 
+      return data
+  
+    known_json_properties = ['vehicleType', 'length', 'additionalProperties']
+    additional_properties = data.get('additional_properties', {})
+    for obj_key in list(data.keys()):
+      if not known_json_properties.__contains__(obj_key):
+        additional_properties[obj_key] = data.pop(obj_key, None)
+    data['additional_properties'] = additional_properties
+    return data
+
+",
+]
+`;
+
 exports[`PYTHON_PYDANTIC_PRESET should render nullable union 1`] = `
 Array [
   "class NullableUnionTest(BaseModel):