Spaces:
Build error
Build error
| from rest_framework import serializers | |
| from .models import User, Place, Review | |
| class UserSerializer(serializers.ModelSerializer): | |
| """Serializer for user registration and display.""" | |
| class Meta: | |
| model = User | |
| fields = ['id', 'name', 'phone'] | |
| read_only_fields = ['id'] | |
| def create(self, validated_data): | |
| """Create a new user with phone authentication.""" | |
| user = User.objects.create_user( | |
| phone=validated_data['phone'], | |
| name=validated_data['name'], | |
| username=validated_data['phone'] # Use phone as username | |
| ) | |
| return user | |
| class PlaceSerializer(serializers.ModelSerializer): | |
| """Serializer for place list/search results.""" | |
| average_rating = serializers.SerializerMethodField() | |
| class Meta: | |
| model = Place | |
| fields = ['id', 'name', 'address', 'average_rating'] | |
| read_only_fields = ['id'] | |
| def get_average_rating(self, obj): | |
| """Get the average rating for this place.""" | |
| return obj.average_rating | |
| class ReviewSerializer(serializers.ModelSerializer): | |
| """Serializer for reviews with user details.""" | |
| user_name = serializers.CharField(source='user.name', read_only=True) | |
| class Meta: | |
| model = Review | |
| fields = ['id', 'user_name', 'rating', 'text', 'created_at'] | |
| read_only_fields = ['id', 'user_name', 'created_at'] | |
| class PlaceDetailSerializer(serializers.ModelSerializer): | |
| """Detailed serializer for a single place with all reviews.""" | |
| average_rating = serializers.SerializerMethodField() | |
| reviews = serializers.SerializerMethodField() | |
| class Meta: | |
| model = Place | |
| fields = ['id', 'name', 'address', 'average_rating', 'reviews'] | |
| read_only_fields = ['id'] | |
| def get_average_rating(self, obj): | |
| """Get the average rating for this place.""" | |
| return obj.average_rating | |
| def get_reviews(self, obj): | |
| """ | |
| Get all reviews sorted with current user's review first, | |
| then all others sorted by newest first. | |
| """ | |
| request = self.context.get('request') | |
| if not request or not request.user.is_authenticated: | |
| reviews = obj.reviews.all() | |
| else: | |
| # Get current user's review | |
| user_review = obj.reviews.filter(user=request.user).first() | |
| # Get all other reviews | |
| other_reviews = obj.reviews.exclude(user=request.user).order_by('-created_at') | |
| # Combine: user's review first, then others | |
| if user_review: | |
| reviews = [user_review] + list(other_reviews) | |
| else: | |
| reviews = list(other_reviews) | |
| return ReviewSerializer(reviews, many=True).data | |
| class AddReviewSerializer(serializers.Serializer): | |
| """Serializer for adding a review (creates place if needed).""" | |
| place_name = serializers.CharField(max_length=255) | |
| place_address = serializers.CharField() | |
| rating = serializers.IntegerField(min_value=1, max_value=5) | |
| review_text = serializers.CharField() | |
| def validate(self, data): | |
| """Validate the review data.""" | |
| return data | |
| def create(self, validated_data): | |
| """ | |
| Create a review and associated place if it doesn't exist. | |
| Uses get_or_create to ensure atomic operation. | |
| """ | |
| user = self.context['request'].user | |
| # Get or create the place | |
| place, created = Place.objects.get_or_create( | |
| name=validated_data['place_name'], | |
| address=validated_data['place_address'] | |
| ) | |
| # Create or update the review | |
| review, created = Review.objects.update_or_create( | |
| user=user, | |
| place=place, | |
| defaults={ | |
| 'rating': validated_data['rating'], | |
| 'text': validated_data['review_text'] | |
| } | |
| ) | |
| return review | |