This commit is contained in:
2026-04-06 23:50:24 +03:30
parent a67236d45c
commit ff464cb4a5
140 changed files with 2061 additions and 2702 deletions
@@ -0,0 +1,107 @@
"""
Management command to seed a fixed demo farm center location and soil depths.
Run: python manage.py seed_location_data
"""
from django.core.management.base import BaseCommand
from location_data.models import SoilDepthData, SoilLocation
DEMO_LATITUDE = "50.000000"
DEMO_LONGITUDE = "50.000000"
DEMO_BOUNDARY = {
"type": "Polygon",
"coordinates": [
[
[49.995, 49.995],
[50.005, 49.995],
[50.005, 50.005],
[49.995, 50.005],
[49.995, 49.995],
]
],
}
DEMO_SOIL_DEPTHS = {
SoilDepthData.DEPTH_0_5: {
"bdod": 1.22,
"cec": 18.4,
"cfvo": 3.0,
"clay": 24.0,
"nitrogen": 0.21,
"ocd": 26.0,
"ocs": 4.1,
"phh2o": 6.7,
"sand": 38.0,
"silt": 38.0,
"soc": 1.8,
"wv0010": 0.32,
"wv0033": 0.24,
"wv1500": 0.12,
},
SoilDepthData.DEPTH_5_15: {
"bdod": 1.28,
"cec": 17.2,
"cfvo": 4.0,
"clay": 26.0,
"nitrogen": 0.18,
"ocd": 23.0,
"ocs": 3.6,
"phh2o": 6.8,
"sand": 36.0,
"silt": 38.0,
"soc": 1.5,
"wv0010": 0.29,
"wv0033": 0.22,
"wv1500": 0.11,
},
SoilDepthData.DEPTH_15_30: {
"bdod": 1.34,
"cec": 15.9,
"cfvo": 5.0,
"clay": 28.0,
"nitrogen": 0.14,
"ocd": 19.0,
"ocs": 2.9,
"phh2o": 6.9,
"sand": 34.0,
"silt": 38.0,
"soc": 1.2,
"wv0010": 0.26,
"wv0033": 0.19,
"wv1500": 0.09,
},
}
class Command(BaseCommand):
help = "Seed a fixed center location at 50.00, 50.00 plus three soil depth rows."
def handle(self, *args, **options):
location, created = SoilLocation.objects.update_or_create(
latitude=DEMO_LATITUDE,
longitude=DEMO_LONGITUDE,
defaults={
"task_id": "",
"farm_boundary": DEMO_BOUNDARY,
},
)
status_text = "Created" if created else "Updated"
self.stdout.write(
self.style.SUCCESS(
f"{status_text} SoilLocation id={location.id} at ({location.latitude}, {location.longitude})"
)
)
for depth_label, values in DEMO_SOIL_DEPTHS.items():
_, depth_created = SoilDepthData.objects.update_or_create(
soil_location=location,
depth_label=depth_label,
defaults=values,
)
depth_status = "Created" if depth_created else "Updated"
self.stdout.write(
self.style.SUCCESS(f" {depth_status} SoilDepthData {depth_label}")
)
self.stdout.write(self.style.SUCCESS("\nDone seeding location_data demo records."))
@@ -0,0 +1,15 @@
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("location_data", "0005_merge_20260327_0840"),
]
operations = [
migrations.RemoveField(
model_name="soillocation",
name="ideal_sensor_profile",
),
]
+14 -11
View File
@@ -3,7 +3,7 @@ from django.db import models
class SoilLocation(models.Model):
"""
مختصات جغرافیایی برای داده‌های خاک.
مرکز زمین برای داده‌های خاک و مزرعه.
هر مختصات سه سطر در SoilDepthData دارد (۰–۵، ۵–۱۵، ۱۵–۳۰ سانتی‌متر).
"""
@@ -11,27 +11,20 @@ class SoilLocation(models.Model):
max_digits=9,
decimal_places=6,
db_index=True,
help_text="عرض جغرافیایی (lat)",
help_text="عرض جغرافیایی مرکز زمین (lat)",
)
longitude = models.DecimalField(
max_digits=9,
decimal_places=6,
db_index=True,
help_text="طول جغرافیایی (lon)",
help_text="طول جغرافیایی مرکز زمین (lon)",
)
task_id = models.CharField(
max_length=255,
blank=True,
help_text="شناسه تسک Celery در حال پردازش",
)
ideal_sensor_profile = models.JSONField(
default=dict,
blank=True,
help_text=(
"پروفایل ایده‌آل سنسورها برای این مزرعه/لوکیشن. "
'نمونه: {"moisture": {"ideal": 0.65, "min": 0.50, "max": 0.80}}'
),
)
farm_boundary = models.JSONField(
default=dict,
blank=True,
@@ -51,10 +44,20 @@ class SoilLocation(models.Model):
)
]
ordering = ["-updated_at"]
verbose_name = "مرکز زمین"
verbose_name_plural = "مراکز زمین"
def __str__(self):
return f"SoilLocation({self.latitude}, {self.longitude})"
@property
def center_latitude(self):
return self.latitude
@property
def center_longitude(self):
return self.longitude
@property
def is_complete(self):
"""آیا هر سه عمق ذخیره شده‌اند؟"""