MarisiaS / SMM

0 stars 0 forks source link

Registering Schools #16

Closed MarisiaS closed 7 months ago

MarisiaS commented 7 months ago

This issue is part of #15

Description

Create Model: Develop a Django model named "School" with the required fields: Name, Open_hour and Close_hour. Implement appropriate data types and constraints for each field.

Create Serializer and Viewset: Develop a Django REST framework (DRF)serializer and viewset for the "School" model, focusing on Read operations.

Fixture File: Create a Django fixture file to populate the database with the example school "Flying Fish."

viriponce commented 7 months ago

@MarisiaS

I'm working on these issue but I have a couple of questions:

name: In the site model, we have name as Unique. In School, is it need to be unique? Can we have more than one school with the same name? If yes, should we add any other fields to this model to differentiate them?

open_time, close_time: I'm guessing these can be null/blank? If so, there are some technical considerations: TimeField doesn't allow blank values by default, a request with the following values will get a Bad request response:

{ "name": "Flying Fish", "open_time": "", "close_time": "" } RESPONSE: { "open_time": [ "Time has wrong format. Use one of these formats instead: hh:mm[:ss[.uuuuuu]]." ], "close_time": [ "Time has wrong format. Use one of these formats instead: hh:mm[:ss[.uuuuuu]]." ] }

I have found two possible solutions:

  1. We can create a subclass of TimeField that allow blank values and use it in the serializer:
class BlankableTimeField(serializers.TimeField):
    def to_internal_value(self, value):
        if value == '':
            return None
        return super().to_internal_value(value)

class SchoolSerializer(serializers.ModelSerializer):
    name = serializers.CharField(max_length=50)
    open_time = BlankableTimeField(required=False)
    close_time = BlankableTimeField(required=False)
  1. Use CharField for open_time and close_time fields and perform the validation manually in the serializer, converting the string representation to a datetime object:
class SchoolSerializer(serializers.ModelSerializer):
    name = serializers.CharField(max_length=50)
    open_time = serializers.CharField(required=False, allow_blank=True)
    close_time = serializers.CharField(required=False, allow_blank=True)

    def validate_open_time(self, value):
        return self.validate_time_field(value)

    def validate_close_time(self, value):
        return self.validate_time_field(value)

    def validate_time_field(self, value):
        if not value:
            return None 
        try:
            # Try to parse the time string
            return datetime.datetime.strptime(value, '%H:%M').time()
        except ValueError:
            raise serializers.ValidationError("Invalid time format. Use hh:mm.")

    class Meta:
        model = School
        fields = ('id', 'name', 'open_time', 'close_time')
MarisiaS commented 7 months ago

Hi Viri!

I'm working on these issue but I have a couple of questions:

name: In the site model, we have name as Unique. In School, is it need to be unique? Can we have more than one school with the same name? If yes, should we add any other fields to this model to differentiate them?

I think for now we could make name unique.

open_time, close_time: I'm guessing these can be null/blank? If so, there are some technical considerations: TimeField doesn't allow blank values by default, a request with the following values will get a Bad request response:

{ "name": "Flying Fish", "open_time": "", "close_time": "" } RESPONSE: { "open_time": [ "Time has wrong format. Use one of these formats instead: hh:mm[:ss[.uuuuuu]]." ], "close_time": [ "Time has wrong format. Use one of these formats instead: hh:mm[:ss[.uuuuuu]]." ] }

I have found two possible solutions:

  1. We can create a subclass of TimeField that allow blank values and use it in the serializer:
class BlankableTimeField(serializers.TimeField):
    def to_internal_value(self, value):
        if value == '':
            return None
        return super().to_internal_value(value)

class SchoolSerializer(serializers.ModelSerializer):
    name = serializers.CharField(max_length=50)
    open_time = BlankableTimeField(required=False)
    close_time = BlankableTimeField(required=False)
  1. Use CharField for open_time and close_time fields and perform the validation manually in the serializer, converting the string representation to a datetime object:
class SchoolSerializer(serializers.ModelSerializer):
    name = serializers.CharField(max_length=50)
    open_time = serializers.CharField(required=False, allow_blank=True)
    close_time = serializers.CharField(required=False, allow_blank=True)

    def validate_open_time(self, value):
        return self.validate_time_field(value)

    def validate_close_time(self, value):
        return self.validate_time_field(value)

    def validate_time_field(self, value):
        if not value:
            return None 
        try:
            # Try to parse the time string
            return datetime.datetime.strptime(value, '%H:%M').time()
        except ValueError:
            raise serializers.ValidationError("Invalid time format. Use hh:mm.")

    class Meta:
        model = School
        fields = ('id', 'name', 'open_time', 'close_time')

I like the blankable field solution.

Thanks Viri.