123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- from rest_framework import serializers
- from .models import City, Attraction, UserPreference, TravelPlan, DayPlan, DayPlanAttraction
- from django.contrib.auth import get_user_model
- User = get_user_model()
- # class CitySerializer(serializers.ModelSerializer):
- # is_available = serializers.BooleanField(source='is_hot') # Map is_hot to is_available
- #
- # class Meta:
- # model = City
- # fields = ['id', 'name', 'is_available'] # Keep is_available in response
- #
- #
- # class AttractionSerializer(serializers.ModelSerializer):
- # city = CitySerializer(read_only=True)
- #
- # class Meta:
- # model = Attraction
- # fields = ['id', 'city', 'name', 'description', 'short_desc', 'address',
- # 'ticket_price', 'open_hours', 'image', 'tags', 'is_featured']
- class CitySerializer(serializers.ModelSerializer):
- class Meta:
- model = City
- fields = ['id', 'name', 'code', 'image', 'description']
- class AttractionSerializer(serializers.ModelSerializer):
- city = CitySerializer(read_only=True)
- tags = serializers.SerializerMethodField()
- image_url = serializers.SerializerMethodField()
- class Meta:
- model = Attraction
- fields = ['id', 'city', 'name', 'description', 'short_desc', 'address',
- 'ticket_price', 'open_hours', 'image_url', 'tags', 'is_featured']
- def get_tags(self, obj):
- # 确保返回的是列表,即使数据库中是字符串
- if isinstance(obj.tags, str):
- return [tag.strip() for tag in obj.tags.split(',')]
- return obj.tags or []
- def get_image_url(self, obj):
- if obj.image:
- return obj.image.url
- return None
- class RedTourismPlanSerializer(serializers.Serializer):
- title = serializers.CharField()
- description = serializers.CharField()
- days = serializers.ListField(child=serializers.DictField())
- red_tourism_tips = serializers.ListField(
- child=serializers.CharField(),
- required=False
- )
- suitable_for = serializers.CharField(
- required=False,
- default="适合党员干部、学生团体等"
- )
- def validate(self, data):
- """验证至少包含2个红色景点"""
- red_attractions = 0
- for day in data.get('days', []):
- for att in day.get('attractions', []):
- if att.get('is_red_tourism', False):
- red_attractions += 1
- if red_attractions < 2:
- raise serializers.ValidationError("行程必须包含至少2个红色景点")
- return data
- class UserPreferenceSerializer(serializers.ModelSerializer):
- cities = CitySerializer(many=True, read_only=True)
- class Meta:
- model = UserPreference
- fields = ['id', 'cities', 'days', 'interests', 'transport', 'custom_requirements']
- class DayPlanAttractionSerializer(serializers.ModelSerializer):
- attraction = AttractionSerializer(read_only=True)
- class Meta:
- model = DayPlanAttraction
- fields = ['id', 'attraction', 'order', 'visit_time', 'notes']
- class DayPlanSerializer(serializers.ModelSerializer):
- attractions = DayPlanAttractionSerializer(many=True, read_only=True)
- class Meta:
- model = DayPlan
- fields = ['id', 'day', 'theme', 'description', 'transport', 'attractions']
- class TravelPlanSerializer(serializers.ModelSerializer):
- day_plans = DayPlanSerializer(many=True, read_only=True)
- class Meta:
- model = TravelPlan
- fields = ['id', 'title', 'description', 'days', 'suitable_for', 'status', 'day_plans', 'created_at']
- class TravelPlanCreateSerializer(serializers.ModelSerializer):
- class Meta:
- model = TravelPlan
- fields = ['preference', 'title', 'description', 'days', 'suitable_for']
- class UserPreferenceCreateSerializer(serializers.ModelSerializer):
- city_ids = serializers.ListField(
- child=serializers.IntegerField(),
- write_only=True,
- required=True
- )
- class Meta:
- model = UserPreference
- fields = ['city_ids', 'days', 'interests', 'transport', 'custom_requirements']
- def create(self, validated_data):
- city_ids = validated_data.pop('city_ids')
- preference = UserPreference.objects.create(**validated_data)
- preference.cities.set(city_ids)
- return preference
|