Django Management Command Not Triggering API Update in Frontend: Debugging Connection Issues Between Django Backend and React Frontend

    from django.core.management.base import BaseCommand
    from myapi.models import StrengthWknes, CustomUser
    import pandas as pd
    from sklearn.neighbors import NearestNeighbors
    from sklearn.linear_model import LinearRegression
    import numpy as np

    class Command(BaseCommand):
        help = 'Create study groups based on normalized percentages using k-NN and predict target score for the weakest subject'

        def add_arguments(self, parser):
            parser.add_argument('grade', type=str, help='Grade for which to create study groups')
            parser.add_argument('current_user_id', type=int, help='ID of the current user')
            parser.add_argument('n_neighbors', type=int, default=5, help='Number of neighbors to find')

        def handle(self, *args, **kwargs):
            grade = kwargs['grade']
            current_user_id = kwargs['current_user_id']
            n_neighbors = kwargs['n_neighbors']
            
            user_data = self.fetch_user_data(grade)
            group_usernames, group_df = self.create_study_group(user_data, current_user_id, n_neighbors)
            
            if len(group_usernames) < 3:
                self.stdout.write(self.style.WARNING('Group is too small. Select group manually.'))
            else:
                self.stdout.write(self.style.SUCCESS(f'Created group: {group_usernames}'))
                
                # Predict target score for the weakest subject
                if not group_df.empty:
                    target_scores = self.predict_target_score(group_df, current_user_id)
                    self.stdout.write(self.style.SUCCESS(f'Target scores for the weakest subject: {target_scores}'))

        def fetch_user_data(self, grade):
            records = StrengthWknes.objects.filter(grade__grade=grade)
            data = []
            for record in records:
                user = CustomUser.objects.get(pk=record.id.id)
                data.append({
                    'user_id': user.id,
                    'username': user.username,
                    'normalized_percentage': record.normalized_percentage,
                    'strgth_wkness': record.strgth_wkness
                })
            df = pd.DataFrame(data)
            self.stdout.write(self.style.SUCCESS(f'Fetched user data:\n{df}'))
            return df

        def create_study_group(self, df, current_user_id, n_neighbors):
            TOLERANCE = 10  # Tolerance percentage range for neighbor selection
            MAX_DIFF = 10   # Maximum allowed difference within the group

            if len(df) < n_neighbors:
                return [], pd.DataFrame()  # Return empty group and DataFrame

            df['normalized_percentage'] = df['normalized_percentage'].astype(float)
            
            # Prepare data for k-NN
            X = df[['normalized_percentage']].values
            current_user = df[df['user_id'] == current_user_id]
            if current_user.empty:
                return [], pd.DataFrame()

            current_user_percentage = current_user['normalized_percentage'].values.reshape(1, -1)
            
            # Initialize and fit the k-NN model
            knn = NearestNeighbors(n_neighbors=n_neighbors, metric='euclidean')
            knn.fit(X)
            
            # Find nearest neighbors
            distances, indices = knn.kneighbors(current_user_percentage)
            
            # Get the neighbors
            neighbor_indices = indices.flatten()
            group_df = df.iloc[neighbor_indices]
            
            # Ensure the current user is included
            if current_user_id not in group_df['user_id'].values:
                group_df = pd.concat([group_df, current_user])

            # Filter out users based on TOLERANCE and MAX_DIFF
            current_user_percentage = current_user['normalized_percentage'].values[0]
            group_df = group_df[(
                (group_df['normalized_percentage'] - current_user_percentage).abs() <= MAX_DIFF
            )]

            def within_tolerance(row, group_df):
                return all(
                    abs(row['normalized_percentage'] - other['normalized_percentage']) <= TOLERANCE
                    for _, other in group_df.iterrows()
                )

            group_df = group_df[group_df.apply(lambda row: within_tolerance(row, group_df), axis=1)]
            
            # If the group is too small, attempt to add more users
            while len(group_df) < n_neighbors:
                additional_users = df[~df['user_id'].isin(group_df['user_id'])]
                additional_users = additional_users[(
                    (additional_users['normalized_percentage'] - current_user_percentage).abs() <= MAX_DIFF
                )]
                
                if additional_users.empty:
                    break
                
                # Re-check tolerance for additional users
                def is_tolerant(row, group_df):
                    return within_tolerance(row, group_df)

                additional_users = additional_users[additional_users.apply(lambda row: is_tolerant(row, group_df), axis=1)]
                
                if not additional_users.empty:
                    group_df = pd.concat([group_df, additional_users.head(1)])
            
            group_usernames = group_df['username'].tolist()

            # Fetch and display the strgth_wkness JSON data for all users in the group
            group_ids = group_df['user_id'].tolist()
            strgth_wkness_data = StrengthWknes.objects.filter(id__in=group_ids)
            strgth_wkness_dict = {user.id: user.strgth_wkness for user in strgth_wkness_data}
            
            self.stdout.write(self.style.SUCCESS(f'Group formation:\n{group_df}'))
            self.stdout.write(self.style.SUCCESS(f'Created group: {group_usernames}'))
            self.stdout.write(self.style.SUCCESS(f'Strengths and weaknesses of users in the group:\n{strgth_wkness_dict}'))

            return group_usernames, group_df

        def predict_target_score(self, group_df, current_user_id):
            # Identify the current user's data
            current_user = group_df[group_df['user_id'] == current_user_id]
            if current_user.empty:
                return {'message': 'Current user not found in the group.'}

            # Fetch current user's strengths and weaknesses
            strgth_wkness = current_user['strgth_wkness'].iloc[0]
            print("Current user strengths and weaknesses:", strgth_wkness)

            # Check if all scores are the same
            unique_scores = set(strgth_wkness.values())
            if len(unique_scores) == 1:
                return {'message': 'All subjects have the same score. Focus on overall improvement.'}

            # Find the weakest subject for the current user
            weakest_subject = min(strgth_wkness, key=lambda k: strgth_wkness[k])
            weakest_subject_scores = [
                user['strgth_wkness'].get(weakest_subject, 0) for _, user in group_df.iterrows()
            ]

            # Debug: Log the weakest subject and its scores
            print(f"Weakest subject: {weakest_subject}")
            print("Weakest subject scores:", weakest_subject_scores)

            if not weakest_subject_scores:
                return {'message': 'No scores available for the weakest subject.'}

            # Prepare data for regression
            X_train = np.array(range(len(weakest_subject_scores))).reshape(-1, 1)  # Indexes as feature
            y_train = np.array(weakest_subject_scores)

            # Create and train the model
            model = LinearRegression()
            model.fit(X_train, y_train)

            # Predict the target score for the current user
            current_user_index = len(weakest_subject_scores)  # Index for prediction
            predicted_score = model.predict(np.array([[current_user_index]]))
            target_score = round(predicted_score[0])

            # Adjust target score if it is lower than current user's score
            current_score = strgth_wkness[weakest_subject]
            if target_score <= current_score:
                target_score = min(current_score + 1, 5)  # Ensure target score does not exceed maximum

            # Suggest the group member with the highest score in the weakest subject
            higher_scores = [score for score in weakest_subject_scores if score > current_score]
            if higher_scores:
                highest_score_index = weakest_subject_scores.index(max(higher_scores))
                suggested_partner = group_df['username'].tolist()[highest_score_index]
            else:
                suggested_partner = 'No suggestion available, consider focusing on the weakest subject.'

            # Return the target score and the suggested partner
            return {
                'weakest_subject': weakest_subject,
                'target_score': target_score,
                'suggested_partner': suggested_partner
            }

    from django.urls import path
    from .views import signup, ObtainTokenView, get_subjects_by_grade, save_strengths_weaknesses,    get_str_wkn, check_strength_status,update_strength_status,run_create_groups_command

    urlpatterns = [
        path('signup/', signup, name='signup'),
        path('login/', ObtainTokenView.as_view(), name='token_obtain_pair'),
        path('subjects/', get_subjects_by_grade, name='get_subjects_by_grade'),
        path('save-strengths-weaknesses/', save_strengths_weaknesses, name='save-strengths-weaknesses'),
        path('get_str_wkn/', get_str_wkn, name='get_str_wkn'),  
        path('check-strength-status/',check_strength_status, name='check_strength_status'),
        path('update-strength-status/', update_strength_status, name='update_strength_status'),
        path('run-create-groups/', run_create_groups_command, name='run_create_groups'),

    ]
        


  import React, { useState, useEffect } from 'react';
  import { jwtDecode } from 'jwt-decode'; // Adjusted import
  import axios from 'axios';
  import '../css/MakeGroup.css'; // Adjust the path as necessary

  const MakeGroup = () => {
    const [decodedToken, setDecodedToken] = useState(null);
    const [message, setMessage] = useState('');
    const [error, setError] = useState('');
    const [currentUserId, setCurrentUserId] = useState('');
    const [grade, setGrade] = useState('');

    useEffect(() => {
      const storedToken = localStorage.getItem('token');
      if (storedToken) {
        try {
          const decoded = jwtDecode(storedToken); // Use named import
          setDecodedToken(decoded);
          setCurrentUserId(decoded.user_id);
          setGrade(decoded.grade);
        } catch (error) {
          console.error('Error decoding token:', error);
        }
      }
    }, []);

    const handleCreateGroups = () => {
      if (!currentUserId || !grade) {
        setError('Error: Missing user information.');
        return;
      }
    
      console.log('Sending request with:', { current_user_id: currentUserId, grade });
    
      axios.post('http://localhost:8000/api/run-create-groups/', 
        { current_user_id: currentUserId, grade }, 
        {
          headers: {
            Authorization: `Bearer ${localStorage.getItem('token')}`
          }
        }
      )
      .then(response => {
        setMessage(response.data.message);
      })
      .catch(error => {
        setError(error.response ? error.response.data.error : error.message);
      });
    };
    
    console.log('MakeGroup component rendered!');

    return (
      <div className="make-group-wrapper">
        <div className="make-group-container">
          <h2 className="make-group-heading">Create Study Groups</h2>
          <button className="create-groups-button" onClick={handleCreateGroups}>
            Create Groups
          </button>
          {message && <p className="message-text">{message}</p>}
          {error && <p className="error-text">{error}</p>}
        </div>
      </div>
    );
  };

  export default MakeGroup;

Running the Django Management Command:

I executed a custom Django management command that fetches user data, creates study groups using k-NN, and predicts target scores based on the weakest subject. The command worked as expected when run via the Django shell, providing the correct user data, forming groups, and calculating target scores. Integration with Frontend:

I attempted to trigger this functionality from the React frontend by making a GET request to the Django API endpoint designed to create study groups based on user data. The API call worked correctly, and the backend provided the expected response when tested with tools like curl or requests. What I Was Expecting:

I expected that triggering the management command from the React frontend via the API would properly execute the group creation logic in the backend and reflect the changes in the frontend. Specifically, I anticipated seeing updates in the React application that would indicate successful group formation and the predicted target scores. Current Issue:

The Django management command runs correctly in isolation, but when trying to connect it with the React frontend through the API, the frontend does not receive the expected updates or reflect changes based on the backend processing.

! curl -X GET "http://localhost:8000/api/run-create-groups/?current_user_id=93&grade=8"
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzI1ODAzNTgxLCJpYXQiOjE3MjU3OTk5ODEsImp0aSI6IjI1MTVmMTU2NTE5NjQwNjZhMGE1M2UwMjhjYTNlMjU0IiwidXNlcl9pZCI6OTMsImVtYWlsIjoiYXJ5YW5AZ21haWwuY29tIiwidXNlcm5hbWUiOiJBcnlhbiIsImdyYWRlIjoiOCIsInN0YXRlIjoiTWl6b3JhbSJ9.VZ4Xgu31CNDNSgwOm63BYOhcrmSmh8nLNM9DLnJgK2A"

Back to Top