i have some problems when processing image, fix that issue, its odoo17 and fastapi, see files and fix issue, dont touch to client side api and xml structure, project is in prod and we need to change only logics that will not crash app in admin panel nor in mobile side, heres files:
router: from typing import Optional, Annotated, List
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, Request
from odoo.api import Environment
from odoo.addons.base.models.res_partner import Partner
from odoo.addons.fastapi_addon.schemas.base_schema import PagedCollection
from odoo.addons.fastapi_addon.utils.media_url import get_media_url
from odoo import _
from ..dependencies import odoo_env, get_partner_with_session
from ..schemas.tashabbuskor_schema import (
ApplicationList,
ApplicationDetail,
ApplicationCreate,
UserApplicationsList,
ApplicationCategoryBase,
ApplicationSubcategoryBase,
ApplicationCategoryWithSubcategories
)

router = APIRouter(prefix="/applications", tags=["Applications"])

@router.get("/categories", response_model=List[ApplicationCategoryWithSubcategories])
async def get_application_categories_with_subcategories(
env: Annotated[Environment, Depends(odoo_env)],
partner: Annotated[Partner, Depends(get_partner_with_session)],
):
"""
Get list of all available application categories with their subcategories
"""
# Odoo model classes
ApplicationCategory = env['mahallam.application.category'].sudo()
ApplicationSubcategory = env['mahallam.application.subcategory'].sudo()

# Fetch categories
categories = ApplicationCategory.search([])

# Prepare the response
response = []
for category in categories:
    # Fetch subcategories for each category
    subcategories = ApplicationSubcategory.search([('category_id', '=', category.id)])
    
    # Append category with nested subcategories to the response list
    response.append(
        ApplicationCategoryWithSubcategories(
            id=category.id,
            name=category.name,
            subcategories=[
                ApplicationSubcategoryBase(
                    id=subcategory.id,
                    name=subcategory.name
                )
                for subcategory in subcategories
            ]
        )
    )
    
return response

@router.get("/list", response_model=PagedCollection[ApplicationList])
async def get_applications_list(
env: Annotated[Environment, Depends(odoo_env)],
partner: Annotated[Partner, Depends(get_partner_with_session)],
request: Request,
):
Application = env['mahallam.application'].sudo()
main_home = env['user.home.session'].sudo().search([
('partner_id', '=', partner.id),
('is_main_home', '=', True)
], limit=1)

if not main_home:
    raise HTTPException(status_code=404, detail=_("Main home not found"))

domain = [('mahalla_id', '=', main_home.home_id.mahalla_id.id),('hidden', '=', False)]
applications = Application.search(domain)

items = [
    ApplicationList(
        id=app.id,
        status=app.status,
        photo=get_media_url(app.image_ids[0]._name, app.image_ids[0].id, 'media') if app.image_ids else None,
        description=app.description,
        date=app.created_at,
        category=app.category_id.name if app.category_id else None,
        subcategory=app.subcategory_id.name if app.subcategory_id else None,
        is_author=app.partner_id.id == partner.id,
    )
    for app in applications
]

return PagedCollection[ApplicationList](
    count=len(applications),
    current=str(request.url),
    items=items
)

@router.get("/my", response_model=UserApplicationsList)
async def get_user_applications(
env: Annotated[Environment, Depends(odoo_env)],
partner: Annotated[Partner, Depends(get_partner_with_session)],
request: Request,
):
Application = env['mahallam.application'].sudo()
main_home = env['user.home.session'].sudo().search([
('partner_id', '=', partner.id),
('is_main_home', '=', True)
], limit=1)
domain = [('partner_id', '=', partner.id),('mahalla_id', '=', main_home.home_id.mahalla_id.id)]
applications = Application.search(domain)

items = [
    ApplicationList(
        id=app.id,
        status=app.status,
        photo=get_media_url(app.image_ids[0]._name, app.image_ids[0].id, 'media') if app.image_ids else None,
        description=app.description,
        date=app.created_at,
        category=app.category_id.name if app.category_id else None,
        subcategory=app.subcategory_id.name if app.subcategory_id else None,
        is_author=app.partner_id.id == partner.id
    )
    for app in applications
]

return UserApplicationsList(
    applications=PagedCollection[ApplicationList](
        count=len(applications),
        current=str(request.url),
        items=items
    ),
    total_count=len(applications)
)

@router.get("/{application_id}", response_model=ApplicationDetail)
async def get_application_detail(
application_id: int,
env: Annotated[Environment, Depends(odoo_env)],
partner: Annotated[Partner, Depends(get_partner_with_session)],
):
Application = env['mahallam.application'].sudo()
application = Application.browse(application_id)

if not application.exists():
    raise HTTPException(status_code=404, detail=_("Application not found"))

return ApplicationDetail(
    id=application.id,
    status=application.status,
    description=application.description,
    date=application.created_at,
    category=application.category_id.name if application.category_id else None,
    subcategory=application.subcategory_id.name if application.subcategory_id else None,
    state=[(state.name, state.description) for state in application.state_id],
    images=[
        get_media_url(media._name, media.id, 'media')
        for media in application.image_ids
    ],
    after_images=[
        get_media_url(media._name, media.id, 'media')
        for media in application.after_image_ids
    ],
    is_author=application.partner_id.id == partner.id,
)

@router.post("/create", response_model=ApplicationDetail)
async def create_application(
env: Annotated[Environment, Depends(odoo_env)],
partner: Annotated[Partner, Depends(get_partner_with_session)],
category_id: int = Form(...),
subcategory_id: int = Form(...),
description: str = Form(...),
latitude: float = Form(...),
longitude: float = Form(...),
media_files: List[UploadFile] = File(...),
):
Application = env['mahallam.application'].sudo()
ApplicationMedia = env['mahallam.application.media'].sudo()

main_home = partner.home_ids.filtered(lambda h: h.is_main_home)

application_vals = {
    'category_id': category_id,
    'subcategory_id': subcategory_id,
    'description': description,
    'latitude': latitude,
    'longitude': longitude,
    'status': 'created',
    'partner_id': partner.id,
}
if main_home:
    application_vals.update({
        'mahalla_id': main_home.home_id.mahalla_id.id,
        'district_id': main_home.home_id.district_id.id,
        'region_id': main_home.home_id.region_id.id,
    })

application = Application.create(application_vals)

for media_file in media_files:
    content = await media_file.read()
    ApplicationMedia.create({
        'application_id': application.id,
        'media': content,
        'media_name': media_file.filename
    })

return await get_application_detail(application.id, env, partner)

@router.post("/{application_id}/complete", response_model=ApplicationDetail)
async def complete_application(
application_id: int,
env: Annotated[Environment, Depends(odoo_env)],
partner: Annotated[Partner, Depends(get_partner_with_session)],
):
Application = env['mahallam.application'].sudo()
application = Application.browse(application_id)

if not application.exists():
    raise HTTPException(status_code=404, detail=_("Application not found"))

if application.partner_id.id != partner.id:
    raise HTTPException(status_code=403, detail=_("Not authorized to complete this application"))

if application.status not in ['created', 'in_progress']:
    raise HTTPException(
        status_code=400,
        detail=f"Cannot complete application in {application.status} status")

application.write({'status': 'completed'})

return await get_application_detail(application_id, env, partner)

@router.post("/{application_id}/cancel", response_model=ApplicationDetail)
async def cancel_application(
application_id: int,
env: Annotated[Environment, Depends(odoo_env)],
partner: Annotated[Partner, Depends(get_partner_with_session)],
):
Application = env['mahallam.application'].sudo()
application = Application.browse(application_id)

if not application.exists():
    raise HTTPException(status_code=404, detail=_("Application not found"))

if application.partner_id.id != partner.id:
    raise HTTPException(status_code=403, detail=_("Not authorized to cancel this application"))

if application.status not in ['created', 'in_progress']:
    raise HTTPException(
        status_code=400,
        detail=f"Cannot cancel application in {application.status} status"
    )

application.write({'status': 'cancelled'})

return await get_application_detail(application_id, env, partner)

xml:


mahallam.application.tree
mahallam.application











<!-- Form View for mahallam.application -->
<record id="view_mahallam_application_form" model="ir.ui.view">
    <field name="name">mahallam.application.form</field>
    <field name="model">mahallam.application</field>
    <field name="arch" type="xml">
        <form string="Application">
            <sheet>
                <group>
                    <group>
                        <field name="name" placeholder="Enter Application Name"/>
                        <field name="partner_id" readonly="1"/>
                        <field name="category_id"/>
                        <field name="subcategory_id"/>
                        <field name="status"/>
                        <field name="state_id"/>
                        <field name="hidden"/>
                    </group>
                    <group>
                        <field name="mahalla_id" readonly="1"/>
                        <field name="district_id" readonly="1"/>
                        <field name="region_id" readonly="1"/>
                        <field name="created_at" readonly="1"/>
                    </group>
                </group>

                <notebook>
                    <page string="Body">
                        <field name="description"/>
                    </page>
                    <page string="Images">
                        <field name="image_ids">
                            <tree editable="bottom" string="Media">
                                <field name="media_name"/>
                                <field name="media"/>
                            </tree>
                        </field>
                        <field name="after_image_ids">
                            <tree editable="bottom" string="After Media">
                                <field name="media_name"/>
                                <field name="media"/>
                            </tree>
                        </field>
                    </page>
                    <page string="Location">
                        <group>
                            <field name="latitude"/>
                            <field name="longitude"/>
                        </group>
                    </page>
                </notebook>
            </sheet>
        </form>
    </field>
</record>

<!-- Action to Open Tree and Form Views -->
<record id="action_mahallam_application" model="ir.actions.act_window">
    <field name="name">Applications</field>
    <field name="res_model">mahallam.application</field>
    <field name="view_mode">tree,form</field>
    <field name="help" type="html">
        <p class="oe_view_nocontent_create">
            Create your first application
        </p>
    </field>
</record>

<!-- Menu Item for Applications -->
<menuitem id="menu_mahallam_application" name="Tashabuskor" web_icon="mahallam,static/src/img/entrepreneur.png" action="action_mahallam_application" sequence="10"/>

model:from odoo import models, fields, api, _ import datetime

class Application(models.Model):
_name = 'mahallam.application'
_description = 'Application'

name = fields.Char(string=_('Nomi'))
partner_id = fields.Many2one('res.partner', string=_('Partner'), required=True, default=lambda self: self.env.user.partner_id)
category_id = fields.Many2one('mahallam.application.category', string=_('Category'))
subcategory_id = fields.Many2one('mahallam.application.subcategory', string=_('Subcategory'))
description = fields.Text(string=_('Description'), required=True)
image_ids = fields.One2many('mahallam.application.media', 'application_id', string=_('Images'))
after_image_ids = fields.One2many('mahallam.application.after.media', 'application_id', string=_('Media'))
count_images = fields.Integer(string=_('Count Images'), compute='_compute_count_images')
hidden = fields.Boolean(string=_('Hidden'), default=False)
count_media = fields.Integer(string=_('Count Media'), compute='_compute_count_media')
status = fields.Selection(
    [
        ('created', _('Created')),
        ('completed', _('Completed')),
        ('in_progress', _('In Progress')),
        ('rejected', _('Rejected')),
        ('cancelled', _('Cancelled')),
    ],
    default="created"
)
state_id = fields.One2many('mahallam.application.state', 'application_id', string=_('Status'))
mahalla_id = fields.Many2one(
    'mahalla', string=_('Home Mahalla'), store=True, readonly=True
)
district_id = fields.Many2one(
    'district', string=_('Home District'), store=True, readonly=True
)
region_id = fields.Many2one(
    'region', string=_('Home Region'), store=True, readonly=True
)
created_at = fields.Datetime(string=_('Created At'), default=datetime.datetime.now())
latitude = fields.Float(string=_('Latitude'))
longitude = fields.Float(string=_('Latitude'))


@api.model
def write(self, vals):
    partner = self.env.user.partner_id
    main_home = partner.home_ids.filtered(lambda h: h.is_main_home)
    if main_home:
        vals.update({
            'mahalla_id': main_home.home_id.mahalla_id.id,
            'district_id': main_home.home_id.district_id.id,
            'region_id': main_home.home_id.region_id.id,
        })
    return super().write(vals)

def write(self, vals):
    res = super().write(vals)
    if 'status' in vals:
        self.env['mobile.app.push.notification'].create({
            'name': 'Application Status Update',
            'body': f'Your application #{self.id} status changed to {vals["status"]}',
            'notification_type': 'application_status',
            'model_name': 'mahallam.application',
            'object_id': self.id,
            'send_notification_to': 'to_partner',
            'partner_ids': [(6, 0, [self.create_uid.partner_id.id])]
        })
    return res

def _compute_count_media(self):
    for application in self:
        application.count_media = len(application.image_ids)

class ApplicationMedia(models.Model):
_name = 'mahallam.application.media'
_description = 'Application Media'

application_id = fields.Many2one('mahallam.application', string='Application', required=True, ondelete='cascade')
media = fields.Binary(string=_('Media'))
media_name = fields.Char(string=_('Name'))

class ApplicationAfterMedia(models.Model):
_name = 'mahallam.application.after.media'
_description = 'Application Media'

application_id = fields.Many2one('mahallam.application', string='Application', required=True, ondelete='cascade')
media = fields.Binary(string=_('Media'))
media_name = fields.Char(string=_('Name'))

class ApplicationCategory(models.Model):
_name = 'mahallam.application.category'
_description = 'Application Categories'

name = fields.Char(string=_('Nomi'))

class ApplicationSubcategory(models.Model):
_name = 'mahallam.application.subcategory'
_description = 'Application Subcategories'

name = fields.Char(string=_('Nomi'))
category_id = fields.Many2one('mahallam.application.category', string=_('Category'))

class ApplicationState(models.Model):
_name = 'mahallam.application.state'
_description = 'Application States'

name = fields.Selection(
    [
        ('created', _('Application Created')),
        ('application_sent', _('Application Sent')),
        ('started_work', _('Department Started Work')),
        ('ended_work', _('Department Ended Work')),
        ('message_sent', _('Message Sent')),
        ('was_addressed', _('Was Addressed')),
    ],
    default="created"
)
description = fields.Char(string=_('Description'))
application_id = fields.Many2one('mahallam.application', string=_('Application'))

utils:from ..settings import STAGE
import random
import string

def unique_str_generator(length=15):
characters = string.ascii_letters + string.digits
random_string = "".join(random.choice(characters) for _ in range(length))
return random_string

def get_media_url(model: str, object_id: int, field_name: str):
if STAGE == "production":
base_url = "https://mahallam-backend.uicgroup.tech"
else:
base_url = "http://localhost:8070"
return f"{base_url}/web/image/{model}/{object_id}/{field_name}/?{unique_str_generator(10)}"
, the task is user should be able to upload photo and videoes in lists, for each image ids

error in creating application, when receiving media from mobile team, when i upload it from admin panel it worked fine