Fix: Preserve stream order in ChannelSerializer PATCH/PUT responses#659
Conversation
The ChannelSerializer.to_representation() method was not respecting the ChannelStream.order field when serializing PATCH/PUT responses. This caused streams to be returned in an arbitrary order rather than the order specified in the request. The update() method correctly saves the stream order to the database using the ChannelStream.order field, and GET requests (with include_streams=True) correctly return ordered streams via get_streams(). However, standard PATCH/PUT responses were using PrimaryKeyRelatedField which doesn't respect the ordering. This fix ensures that all representations (GET, PATCH, PUT) return streams ordered by the channelstream__order field. Impact: - PATCH/PUT responses now correctly reflect the stream order saved - Clients can trust the response data without needing a follow-up GET - No breaking changes - only fixes inconsistent behavior Tested with: - PATCH request with ordered stream IDs - Verified response matches request order - Verified GET request confirms order persisted to database
|
I'm curious, what is the use-case for the api you're fixing? Or are you fixing a bug with this change? |
Error DetailsDiscoveryThis issue was discovered when using StreamFlow to automatically analyze and order channel streams by quality. StreamFlow sends PATCH requests to reorder streams based on quality metrics, then verifies the order was applied correctly. Actual Error Messages from StreamFlowWhat Was Happening
Root CauseThe After the FixThe PATCH response now matches the payload exactly, and verification passes. |
|
Ok thank you for explaining it. That makes sense to me and assumed it was something like that but was curious for sure. |
|
I made some changes to the code to avoid slowness during bulk channel actions and querying channels (which is used in the channel table) |
Test ResultsI tested the updated code with the following API calls:
Both calls made within seconds of each other on the same channel. The first query (with The issue is that This also affects PATCH operations:
The database IS storing the correct order (confirmed by the |
Additional Testing & ThoughtsI've been testing different approaches and wanted to share some observations that might be useful. The prefetch cache optimization makes sense for bulk operations, but in practice the cache doesn't contain streams ordered by I've implemented a workaround in StreamFlow by using The performance difference is probably minimal - it's one additional query per channel serialization, which in most use cases (individual channel updates, single channel retrievals) won't be noticeable. And it guarantees correctness without needing to manage prefetch ordering. Just food for thought - happy to test whatever approach you think is best for Dispatcharr's architecture. |
|
Perfect yes thank you, I figured using I always want to make sure we aren't causing code that would slow down the web ui or other functions. If you could verify the latest changes I'd appreciate it. |
|
Actually, mind just resubmitting since we are just going to use your original code anyway? Sorry I way over thought this one and sent you down a rabbit hole. |
9c4ae6a to
bbe1f63
Compare
|
Done - reverted to the original simple fix. Ready for review. |
|
Perfect. Thanks again! |
Problem
The
ChannelSerializer.to_representation()method was not respecting theChannelStream.orderfield when serializing PATCH/PUT responses. This caused streams to be returned in an arbitrary order rather than the order specified in the request.While the
update()method correctly saves the stream order to the database using theChannelStream.orderfield, and GET requests (withinclude_streams=True) correctly return ordered streams viaget_streams(), standard PATCH/PUT responses were usingPrimaryKeyRelatedFieldwhich doesn't respect the ordering.Solution
This PR modifies the
to_representation()method to ensure that all API responses (GET, PATCH, PUT) return streams ordered by thechannelstream__orderfield.Changes
ChannelSerializer.to_representation()to query streams with.order_by('channelstream__order')for standard responsesinclude_streams=TruecasesImpact
Testing
Tested with: