0
votes

I'm building an API as part of a project for university, However, I have become stuck when working out how to make updates to my custom user model. At present I have a serializer for updating the profile, but when I try to update the table using the serializer, it falls over with error 1406: "Data too long for column 'title' at row 1". I'm not sure how to resolve this at present and was wondering if someone could point me in the right direction

update: So it seems that I was getting the Data too long for column errors because The code I have is appending to the columns instead of just either altering them if the JSON contains data for the field, or leaving them if it does not. So once I'd tinkered with column lengths I was getting the following database row:

(None, 'Anthony'), (None, (None, 'Anthony')), 1, 0, 1, 1, 2019-01-01, ('a test address', 'hello'), (None, None), (None, None), edd, (None, 'boy'), (None, 'there'), (None, None), (None, '282')

model in question:

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), unique=True)
    title =models.CharField(_('Title'), max_length=8, null=True,  blank=True)
    first_name=models.CharField(_('first name(s)'), max_length=100, blank =True)
    last_name=models.CharField(_('last name'), max_length=100, blank = True)
    is_active=models.BooleanField(_('account active'), default=False)
    is_driver = models.BooleanField(_('driver status'), default=False)
    is_staff = models.BooleanField(_('staff status'), default =False)
    is_admin = models.BooleanField(_('admin status'), default =False)

    dob = models.DateField(auto_now_add= True, blank=True)
    address_1=models.CharField(_('address line 1'),max_length=60, null=False, blank=False)
    address_2=models.CharField(_('address line 2'),max_length=60, null=True, blank=True)
    address_3=models.CharField(_('address line 3'),max_length=60, null=True, blank=True)
    city = models.CharField(_('city'),max_length=60, null=False, blank=False)
    county = models.CharField(_('county'),max_length=60, null=False, blank=False)
    postcode = models.CharField(_('postcode'),max_length=8, blank=False, null=False)
    phone_no = models.CharField(_('phone number'),max_length=50, null=True, blank=True)
    mobile_no = models.CharField(_('mobile Number'),max_length=50,null=False, blank=False)
    drivers_licence_number = models.CharField(max_length=30, null=True, blank=True)
    taxi_licence_number=models.CharField(max_length=30, null=True, blank=True)
    driver_photo=models.ImageField(blank=True)
    date_joined=models.DateField(auto_now_add=True, blank=True)
    last_update=models.DateField(auto_now_add=True, blank=True)

serializer in question:

class UserProfileSerializer (serializers.ModelSerializer):
    model = User

    id = serializers.IntegerField(read_only=True)
    dob = serializers.DateField(read_only=True)
    title=serializers.CharField(max_length=8, required=False)
    first_name=serializers.CharField(max_length=80,required=False)
    last_name=serializers.CharField(max_length=80,required=False)
    address_1 = serializers.CharField(max_length=100, required=False)
    address_2 = serializers.CharField(max_length=100,required=False)
    address_3 = serializers.CharField(max_length=100,required=False)
    postcode = serializers.CharField(max_length=10, required=False)
    county = serializers.CharField(max_length=50, required=False)
    city = serializers.CharField(max_length=50, required=False)
    phone_no = serializers.CharField(required=False)
    mobile_no = serializers.CharField(required=False)




    def update (self, instance, validated_data):
        instance.title= validated_data.get('title'), instance.title
        instance.first_name = validated_data.get('first_name'), instance.first_name
        instance.last_name = validated_data.get('last_name'), instance.first_name
        instance.address_1 = validated_data.get('address_1'), instance.address_1
        instance.address_2 = validated_data.get('address_2'), instance.address_2
        instance.address_3 = validated_data.get('address_3'), instance.address_3
        instance.postcode = validated_data.get('postcode'), instance.postcode
        instance.county = validated_data.get('county'), instance.county
        instance.phone_no = validated_data.get('phone_no'),instance.phone_no
        instance.mobile_no = validated_data.get('mobile_no'), instance.mobile_no
        instance.last_update = datetime.now()

        instance.save()
    return instance

View in question:

class UpdateProfile(APIView):
    permission_classes=[permissions.IsAuthenticated]

    def post(self, request, format=None):

        user=request.user
        print (user.id)
        query_set=User.objects.get(id=user.id)
        print("we got a queryset")
        print(query_set)

        serializer=UserProfileSerializer(query_set, data=request.data)


        if serializer.is_valid():

            profile = serializer.save()

            if profile:        
                return Response(user.data, status=status.HTTP_200_OK)

        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Trace from the server console:

Internal Server Error: /editprofile/ Traceback (most recent call last): File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\backends\utils.py", line 85, in _execute return self.cursor.execute(sql, params) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\backends\mysql\base.py", line 71, in execute return self.cursor.execute(query, args) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\MySQLdb\cursors.py", line 250, in execute self.errorhandler(self, exc, value) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\MySQLdb\connections.py", line 50, in defaulterrorhandler raise errorvalue File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\MySQLdb\cursors.py", line 247, in execute res = self._query(query) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\MySQLdb\cursors.py", line 412, in _query rowcount = self._do_query(q) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\MySQLdb\cursors.py", line 375, in _do_query db.query(q) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\MySQLdb\connections.py", line 276, in query _mysql.connection.query(self, query) _mysql_exceptions.DataError: (1406, "Data too long for column 'title' at row 1")

The above exception was the direct cause of the following exception:

Traceback (most recent call last): File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\core\handlers\exception.py", line 34, in inner response = get_response(request) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response response = self.process_exception_by_middleware(e, request) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\core\handlers\base.py", line 124, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view return view_func(*args, **kwargs) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\views\generic\base.py", line 68, in view return self.dispatch(request, *args, **kwargs) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\rest_framework\views.py", line 495, in dispatch response = self.handle_exception(exc) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\rest_framework\views.py", line 455, in handle_exception self.raise_uncaught_exception(exc) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\rest_framework\views.py", line 492, in dispatch response = handler(request, *args, **kwargs) File "C:\Users\clini\git\net302API\Test1\api\views.py", line 68, in post profile = serializer.save() File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\rest_framework\serializers.py", line 209, in save self.instance = self.update(self.instance, validated_data) File "C:\Users\clini\git\net302API\Test1\api\serializers.py", line 137, in update instance.save() File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\contrib\auth\base_user.py", line 73, in save super().save(*args, **kwargs) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\models\base.py", line 718, in save force_update=force_update, update_fields=update_fields) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\models\base.py", line 748, in save_base updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\models\base.py", line 812, in _save_table forced_update) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\models\base.py", line 861, in _do_update return filtered._update(values) > 0 File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\models\query.py", line 712, in _update return query.get_compiler(self.db).execute_sql(CURSOR) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\models\sql\compiler.py", line 1383, in execute_sql cursor = super().execute_sql(result_type) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\models\sql\compiler.py", line 1065, in execute_sql cursor.execute(sql, params) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\backends\utils.py", line 100, in execute return super().execute(sql, params) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\backends\utils.py", line 68, in execute return self._execute_with_wrappers(sql, params, many=False, executor=self._execute) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers return executor(sql, params, many, context) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\backends\utils.py", line 85, in _execute return self.cursor.execute(sql, params) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\utils.py", line 89, in exit raise dj_exc_value.with_traceback(traceback) from exc_value File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\backends\utils.py", line 85, in _execute return self.cursor.execute(sql, params) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\django\db\backends\mysql\base.py", line 71, in execute return self.cursor.execute(query, args) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\MySQLdb\cursors.py", line 250, in execute self.errorhandler(self, exc, value) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\MySQLdb\connections.py", line 50, in defaulterrorhandler raise errorvalue File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\MySQLdb\cursors.py", line 247, in execute res = self._query(query) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\MySQLdb\cursors.py", line 412, in _query rowcount = self._do_query(q) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\MySQLdb\cursors.py", line 375, in _do_query db.query(q) File "C:\Users\clini\MYDOCU~1\LICLIP~1\NET302~1\lib\site-packages\MySQLdb\connections.py", line 276, in query _mysql.connection.query(self, query) django.db.utils.DataError: (1406, "Data too long for column 'title' at row 1")

2
looks like you are setting too long title - here you are setting it only to 8 symbols: title =models.CharField(_('Title'), max_length=8, null=True, blank=True) - Chiefir
I thought this might be the case, but when I pass the code a value for title that is only 3-4 symbols, it throws the same error. - Kale Otter
did u try to make title blank? show full error trace. - Chiefir
Remove the print statement and use a third party app to debug your app - Ochui Princewill

2 Answers

0
votes

Did you maybe update the max_length of the title and did not migrate yet?

0
votes

So To close this issue down, I found the solution. When I wrote the update method for my serializer i was writing them as instance.fieldname =validated.data.get('input_name'),instance.fieldname

When they should have been instance.fieldname =validated.data.get('input_name',instance.fieldname)

Thank you all for the help :)