feat: add client release size bytes

This commit is contained in:
QiuSW
2026-07-13 17:04:59 +08:00
parent 8878769ec5
commit b71564e2bf
13 changed files with 96 additions and 15 deletions
+19 -1
View File
@@ -442,6 +442,7 @@ class ClientLatestReleaseApiTests(TestCase):
sha256: str = "a" * 64,
release_notes: str = "首版 Windows 客户端",
force_update: bool = False,
size_bytes: int | None = None,
) -> DownloadRelease:
return DownloadRelease.objects.create(
platform=platform,
@@ -452,6 +453,7 @@ class ClientLatestReleaseApiTests(TestCase):
sha256=sha256,
release_notes=release_notes,
force_update=force_update,
size_bytes=size_bytes,
)
def test_latest_release_is_public_without_api_key_and_returns_current_release(self):
@@ -460,6 +462,7 @@ class ClientLatestReleaseApiTests(TestCase):
external_url="https://download.example.com/cmhub-1.2.3.exe",
sha256="b" * 64,
release_notes="修复下载入口并补充 SHA256",
size_bytes=18_765_432,
)
response = self.client.get(self.url)
@@ -475,11 +478,13 @@ class ClientLatestReleaseApiTests(TestCase):
"sha256",
"release_notes",
"force_update",
"size_bytes",
"published_at",
},
)
self.assertEqual(response.data["release"]["version"], "1.2.3")
self.assertFalse(response.data["release"]["force_update"])
self.assertEqual(response.data["release"]["size_bytes"], 18_765_432)
self.assertEqual(
response.data["release"]["download_url"],
"https://download.example.com/cmhub-1.2.3.exe",
@@ -517,6 +522,14 @@ class ClientLatestReleaseApiTests(TestCase):
)
self.assertTrue(response.data["release"]["force_update"])
def test_latest_release_returns_null_size_bytes_when_not_configured(self):
self.create_release(size_bytes=None)
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertIsNone(response.data["release"]["size_bytes"])
def test_latest_release_ignores_web_session_and_does_not_return_user_data(self):
user = get_user_model().objects.create_user(
username="release-session-user",
@@ -590,6 +603,7 @@ class ClientLatestReleaseApiTests(TestCase):
self.assertIsNone(response.data["release"])
self.assertEqual(response.data["message"], "暂未发布")
self.assertNotIn("force_update", response.data)
self.assertNotIn("size_bytes", response.data)
def test_latest_release_rejects_invalid_platform(self):
response = self.client.get(f"{self.url}?platform=android")
@@ -630,6 +644,7 @@ class ClientLatestReleaseApiTests(TestCase):
"sha256",
"release_notes",
"force_update",
"size_bytes",
"published_at",
},
)
@@ -649,13 +664,16 @@ class ClientLatestReleaseApiTests(TestCase):
):
self.assertNotIn(forbidden, response_body)
def test_download_release_admin_exposes_force_update(self):
def test_download_release_admin_exposes_release_metadata_fields(self):
registered_admin = admin.site._registry[DownloadRelease]
self.assertIn("force_update", registered_admin.list_display)
self.assertIn("force_update", registered_admin.list_filter)
self.assertIn("size_bytes", registered_admin.list_display)
version_fields = registered_admin.fieldsets[0][1]["fields"]
self.assertIn("force_update", version_fields)
download_fields = registered_admin.fieldsets[1][1]["fields"]
self.assertIn("size_bytes", download_fields)
@override_settings(
+1
View File
@@ -299,6 +299,7 @@ class ClientLatestReleaseView(APIView):
"sha256": release.sha256,
"release_notes": release.release_notes,
"force_update": release.force_update,
"size_bytes": release.size_bytes,
"published_at": timezone.localtime(release.updated_at).isoformat(),
},
},
+2
View File
@@ -11,6 +11,7 @@ class DownloadReleaseAdmin(admin.ModelAdmin):
"is_current",
"force_update",
"download_source",
"size_bytes",
"sha256_short",
"updated_at",
)
@@ -36,6 +37,7 @@ class DownloadReleaseAdmin(admin.ModelAdmin):
"fields": (
"file",
"external_url",
"size_bytes",
"sha256",
)
},
@@ -0,0 +1,25 @@
# Generated by Django 5.2.15 on 2026-07-13
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("portal", "0003_importtemplate"),
]
operations = [
migrations.AddField(
model_name="downloadrelease",
name="size_bytes",
field=models.PositiveBigIntegerField(
blank=True,
help_text="客户端下载文件大小,单位字节;桌面端用于下载后校验。",
null=True,
validators=[django.core.validators.MinValueValidator(1)],
verbose_name="文件大小字节数",
),
),
]
+8 -1
View File
@@ -1,5 +1,5 @@
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.core.validators import MinValueValidator, RegexValidator
from django.db import models, transaction
@@ -13,6 +13,13 @@ class DownloadRelease(models.Model):
version = models.CharField("版本", max_length=64)
file = models.FileField("安装包文件", upload_to="downloads/", blank=True)
external_url = models.URLField("外部下载地址", blank=True)
size_bytes = models.PositiveBigIntegerField(
"文件大小字节数",
null=True,
blank=True,
validators=[MinValueValidator(1)],
help_text="客户端下载文件大小,单位字节;桌面端用于下载后校验。",
)
sha256 = models.CharField(
"SHA256",
max_length=64,