new
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 6.0.1 on 2026-02-12 12:48
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('community', '0007_announcement'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='activity',
|
||||
name='signup_form_config',
|
||||
field=models.JSONField(blank=True, default=list, help_text='配置报名时需要收集的信息,JSON格式,例如:[{"name": "phone", "label": "手机号", "type": "text", "required": true}]', verbose_name='报名表单配置'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='activitysignup',
|
||||
name='signup_info',
|
||||
field=models.JSONField(blank=True, default=dict, verbose_name='报名信息'),
|
||||
),
|
||||
]
|
||||
@@ -14,6 +14,12 @@ class Activity(models.Model):
|
||||
location = models.CharField(max_length=100, verbose_name="活动地点")
|
||||
max_participants = models.IntegerField(default=50, verbose_name="最大报名人数")
|
||||
is_active = models.BooleanField(default=True, verbose_name="是否启用")
|
||||
signup_form_config = models.JSONField(
|
||||
default=list,
|
||||
verbose_name="报名表单配置",
|
||||
blank=True,
|
||||
help_text='配置报名时需要收集的信息,JSON格式,例如:[{"name": "phone", "label": "手机号", "type": "text", "required": true}]'
|
||||
)
|
||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
|
||||
|
||||
def clean(self):
|
||||
@@ -55,6 +61,11 @@ class ActivitySignup(models.Model):
|
||||
activity = models.ForeignKey(Activity, on_delete=models.CASCADE, related_name='signups', verbose_name="活动")
|
||||
user = models.ForeignKey(WeChatUser, on_delete=models.CASCADE, related_name='activity_signups', verbose_name="报名用户")
|
||||
signup_time = models.DateTimeField(auto_now_add=True, verbose_name="报名时间")
|
||||
signup_info = models.JSONField(
|
||||
default=dict,
|
||||
verbose_name="报名信息",
|
||||
blank=True
|
||||
)
|
||||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='confirmed', verbose_name="状态")
|
||||
|
||||
def __str__(self):
|
||||
|
||||
@@ -10,10 +10,12 @@ class ActivitySerializer(serializers.ModelSerializer):
|
||||
fields = '__all__'
|
||||
|
||||
class ActivitySignupSerializer(serializers.ModelSerializer):
|
||||
activity_info = ActivitySerializer(source='activity', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = ActivitySignup
|
||||
fields = ['id', 'activity', 'user', 'signup_time', 'status']
|
||||
read_only_fields = ['signup_time', 'status']
|
||||
fields = ['id', 'activity', 'activity_info', 'user', 'signup_time', 'status', 'signup_info']
|
||||
read_only_fields = ['signup_time', 'status', 'user']
|
||||
|
||||
class TopicMediaSerializer(serializers.ModelSerializer):
|
||||
url = serializers.SerializerMethodField()
|
||||
|
||||
@@ -36,8 +36,26 @@ class ActivityViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
|
||||
if activity.signups.count() >= activity.max_participants:
|
||||
return Response({'error': '活动名额已满'}, status=400)
|
||||
|
||||
# Get signup info
|
||||
signup_info = request.data.get('signup_info', {})
|
||||
|
||||
# Basic validation
|
||||
if activity.signup_form_config:
|
||||
required_fields = [f['name'] for f in activity.signup_form_config if f.get('required')]
|
||||
for field in required_fields:
|
||||
# Simple check: field exists and is not empty string (if it's a string)
|
||||
val = signup_info.get(field)
|
||||
if val is None or (isinstance(val, str) and not val.strip()):
|
||||
# Try to find label for better error message
|
||||
label = next((f['label'] for f in activity.signup_form_config if f['name'] == field), field)
|
||||
return Response({'error': f'请填写: {label}'}, status=400)
|
||||
|
||||
signup = ActivitySignup.objects.create(activity=activity, user=user)
|
||||
signup = ActivitySignup.objects.create(
|
||||
activity=activity,
|
||||
user=user,
|
||||
signup_info=signup_info
|
||||
)
|
||||
serializer = ActivitySignupSerializer(signup)
|
||||
return Response(serializer.data, status=201)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user