Notes
Notes - notes.io |
class UserImageDataAPIView(APIView):
permission_classes = [IsAuthenticated]
PAGE_SIZE = 15
def get(self, request):
try:
start_time = time.time()
user = request.user
last_sync = request.query_params.get('last_sync') # ISO format
start_image_id = request.query_params.get('start_image_id')
last_image_id = request.query_params.get('last_image_id')
user_data_logger.info(
f"Sync request from user {user.id} - "
f"last_sync: {last_sync}, "
f"start_image_id: {start_image_id}, "
f"last_image_id: {last_image_id}"
)
user_images = UploadedImage.objects.filter(user=user)
# CASE 1: First time sync using timestamp
if last_sync is not None:
parsed_sync_time = parse_datetime(last_sync)
if not parsed_sync_time:
return Response(
{"error": "Invalid last_sync datetime format."},
status=status.HTTP_400_BAD_REQUEST
)
images = user_images.filter(
created_at__gt=parsed_sync_time
).order_by('-created_at')[:self.PAGE_SIZE]
if not images.exists():
user_data_logger.info(f"No new images for user {user.id} since {last_sync}")
return Response({
"success": True,
"message": f"All data already synced till {last_sync}",
"data": [],
"is_complete": True
}, status=status.HTTP_200_OK)
# CASE 2: They provide image ID range
elif start_image_id and last_image_id:
try:
last_image_id = int(last_image_id)
except ValueError:
user_data_logger.error(f"Invalid last_image_id: {last_image_id}")
return Response(
{"error": "last_image_id must be an integer"},
status=status.HTTP_400_BAD_REQUEST
)
images = user_images.filter(
id__gt=last_image_id
).order_by('-created_at')[:self.PAGE_SIZE]
if not images.exists():
user_data_logger.info(f"No images after ID {last_image_id} for user {user.id}")
return Response({
"success": True,
"message": f"All data already synced till image_id {last_image_id}",
"data": [],
"is_complete": True
}, status=status.HTTP_200_OK)
# Default fallback – if nothing is provided
else:
user_data_logger.error("Missing required parameters")
return Response({
"success": False,
"error": "Please provide either 'last_sync' or both 'start_image_id' and 'last_image_id'."
}, status=status.HTTP_400_BAD_REQUEST)
# Serialize images
serializer = UserImageDataSerializer(images, many=True)
# Format data as requested
transformed_data = []
for item in serializer.data:
transformed_data.append({
"image_id": item["id"],
"image_url": item["original_image_url"],
"date_time": item["date_time"],
"is_bale": item["is_bale"],
"site_code": item["site_code"],
"latitude": item["latitude"],
"longitude": item["longitude"],
"time_zone": item["time_zone"],
"contamination_percentage": item["contamination_percentage"],
"moisture_percentage": item["moisture_percentage"],
"outthrows_percentage": item["outthrows_percentage"]
# "bale_polygon": item["bale_polygon"]
})
total_time = time.time() - start_time
return Response({
"success": True,
"data": transformed_data,
"sync_info": {
"fetched_images": len(transformed_data),
# "time_taken": f"{total_time:.2f}s",
"is_complete": len(transformed_data) < self.PAGE_SIZE
}
}, status=status.HTTP_200_OK)
except Exception as e:
return Response({
"success": False,
"error": str(e)
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Now the problem is in this logic it's giving me image id shuffled, while I need id in sequence like suppose user's id is 2, and user upload its first image then we'll create a new column in our DB like sync_id, so here sync_id will be 21 (in which 2 is user id and image is first image 1), then same user uploads it's second image then it'll be 22,23,... and suppose this user uploaded 50 images then last image's sync_id will be 250. so I think it'll be always in sequence.
and now how API will work so in first time it'll give me 15 newest images for that user and it'll give me sync_id of images(not need of image_id). and then in response i'll get last sync_id of image so using this I'll get all the images like again I'll provide last_images_id then again it'll give me 15 old images and so on till end then when all data is get or synced then if I'll try to get data so it'll show me message that All data for this user is synced.
let's understand with example, so we have user whose id is 2 and have 50 images with sync_id like from 21 to 250. then in first time it'll give me 250 to 235 images with data. then when I'll provide last sync id which is 235 so it'll give me from 234 to 219. then I'll give again last sync id 219 so again in this manner it goes on when data is comes to 21 id so it means all data is synced so here it'll pass me message that all data for this user is synced.
Now there's somethings to be remember like response manner will be almost same and instead of image_id show me sync_id but without user id means if sync id is 21 so remove user id from preffix and give me last number like 1 only and if sync_id is 250 so it'll give me 50.
so I think you also need to my models here's it:
class UploadedImage(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
original_image_url = models.URLField(max_length=1000)
latitude = models.FloatField(null=True, blank=True)
longitude = models.FloatField(null=True, blank=True)
site_code = models.CharField(max_length=50, null=True, blank=True)
created_at = models.DateTimeField()
def __str__(self):
return f"Image {self.id} by {self.user.email}"
class SegmentationResult(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
image = models.ForeignKey(UploadedImage, on_delete=models.CASCADE, related_name='segmentations')
is_a_bale = models.BooleanField(default=False)
bale_polygons = models.JSONField(null=True, blank=True)
class NFCResult(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
image = models.ForeignKey(UploadedImage, on_delete=models.CASCADE, related_name='nfc_results')
contamination_percentage = models.FloatField(null=True, blank=True)
class MoistureResult(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
image = models.ForeignKey(UploadedImage, on_delete=models.CASCADE, related_name='moisture_results')
moisture_percentage = models.FloatField(null=True, blank=True)
class OutthrowResult(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
image = models.ForeignKey(UploadedImage, on_delete=models.CASCADE, related_name='outthrow_results')
outthrows_percentage = models.FloatField(null=True, blank=True)
class SiteReport(models.Model):
site_code = models.CharField(max_length=50, unique=True)
avg_nfc = models.FloatField(null=True, blank=True)
avg_moisture = models.FloatField(null=True, blank=True)
avg_outthrows = models.FloatField(null=True, blank=True)
last_updated = models.DateTimeField(auto_now=True)
total_images = models.PositiveIntegerField(default=0)
def __str__(self):
return f"Report for {self.site_code}"
def update_averages(self):
from .averages import SiteReportService
return SiteReportService.update_or_create_report(self.site_code)
Note: This approach is thought by me if you find any issue in this approach so please let me know and if it works good so also let me know.
![]() |
Notes is a web-based application for online taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000+ notes created and continuing...
With notes.io;
- * You can take a note from anywhere and any device with internet connection.
- * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
- * You can quickly share your contents without website, blog and e-mail.
- * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
- * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.
Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.
Easy: Notes.io doesn’t require installation. Just write and share note!
Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )
Free: Notes.io works for 14 years and has been free since the day it was started.
You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;
Email: [email protected]
Twitter: http://twitter.com/notesio
Instagram: http://instagram.com/notes.io
Facebook: http://facebook.com/notesio
Regards;
Notes.io Team
