מדריך שנוצר כולו בבינה מלאכותית.

לחץ להאזנה

הקדמה

במדריך זה נבנה אפליקציה מלאה המשתמשת ב-Django לשרת (Backend) וב-React עם TypeScript לצד הלקוח (Frontend). האפליקציה תדמה מערכת השאלת ספרים מהספרייה, ותכלול ניהול מנויים, ספרים והשאלות. נשתמש ב-Django Rest Framework (DRF) כדי לבנות API שיאפשר תקשורת בין ה-Backend ל-Frontend.

שלב 1: התקנת הכלים הנדרשים

  1. Python: הורד והתקן את Python מהאתר הרשמי: Python Downloads.
  2. Node.js: הורד והתקן את Node.js מהאתר הרשמי: Node.js Downloads.
  3. Git: הורד והתקן את Git: Git Downloads.
  4. Visual Studio Code: מומלץ להשתמש בעורך קוד כמו VS Code: VS Code Downloads.

שלב 2: יצירת פרויקט Django

  1. צור תיקייה לפרויקט: פתח את שורת הפקודה או הטרמינל והקלד:
   mkdir library_project
   cd library_project
  1. צור סביבה וירטואלית:
   python -m venv venv
  1. הפעל את הסביבה הוירטואלית:
  • ב-Windows: venv\Scripts\activate
  • ב-macOS/Linux: source venv/bin/activate
  1. התקן את Django ו-DRF:
   pip install django djangorestframework
  1. צור פרויקט Django:
   django-admin startproject backend .
  1. צור אפליקציה בשם "library":
   python manage.py startapp library
  1. הוסף את האפליקציה וה-DRF לקובץ ההגדרות: ערוך את הקובץ backend/settings.py והוסף את 'rest_framework' ו-'library' ל-INSTALLED_APPS:
   INSTALLED_APPS = [
       'django.contrib.admin',
       'django.contrib.auth',
       'django.contrib.contenttypes',
       'django.contrib.sessions',
       'django.contrib.messages',
       'django.contrib.staticfiles',
       'rest_framework',
       'library',
   ]

שלב 3: הגדרת מודלים (Models)

  1. פתח את הקובץ library/models.py והוסף את הקוד הבא:
   from django.db import models

   class Subscriber(models.Model):
       name = models.CharField(max_length=100)
       children_count = models.PositiveIntegerField()

       def __str__(self):
           return self.name

   class Book(models.Model):
       title = models.CharField(max_length=200)
       author = models.CharField(max_length=100)
       copies_available = models.PositiveIntegerField(default=1)

       def __str__(self):
           return self.title

   class Loan(models.Model):
       subscriber = models.ForeignKey(Subscriber, on_delete=models.CASCADE)
       book = models.ForeignKey(Book, on_delete=models.CASCADE)
       loan_date = models.DateField(auto_now_add=True)

       def __str__(self):
           return f"{self.subscriber.name} borrowed {self.book.title}"

הסבר:

  • Subscriber: מודל המייצג מנוי, עם שם ומספר ילדים.
  • Book: מודל המייצג ספר, עם כותרת, מחבר ומספר עותקים זמינים.
  • Loan: מודל המייצג השאלה של ספר על ידי מנוי, כולל תאריך ההשאלה.
  1. ביצוע מיגרציות:
  • צור קבצי מיגרציה: python manage.py makemigrations
  • החל את המיגרציות: python manage.py migrate

שלב 4: יצירת Serializers

  1. צור קובץ בשם library/serializers.py והוסף את הקוד:
   from rest_framework import serializers
   from .models import Subscriber, Book, Loan

   class SubscriberSerializer(serializers.ModelSerializer):
       class Meta:
           model = Subscriber
           fields = '__all__'

   class BookSerializer(serializers.ModelSerializer):
       class Meta:
           model = Book
           fields = '__all__'

   class LoanSerializer(serializers.ModelSerializer):
       class Meta:
           model = Loan
           fields = '__all__'

       def validate(self, data):
           subscriber = data['subscriber']
           loans_count = Loan.objects.filter(subscriber=subscriber).count()
           if loans_count >= subscriber.children_count:
               raise serializers.ValidationError('המנוי הגיע למספר ההשאלות המקסימלי.')
           return data

הסבר:

  • Serializers משמשים להמרת מודלים לפורמט JSON ולהיפך.
  • ב-LoanSerializer הוספנו ולידציה כדי לוודא שמנוי לא יכול להשאיל יותר ספרים מהמותר לו.

שלב 5: יצירת ViewSets

  1. ערוך את הקובץ library/views.py והוסף את הקוד:
   from rest_framework import viewsets
   from .models import Subscriber, Book, Loan
   from .serializers import SubscriberSerializer, BookSerializer, LoanSerializer

   class SubscriberViewSet(viewsets.ModelViewSet):
       queryset = Subscriber.objects.all()
       serializer_class = SubscriberSerializer

   class BookViewSet(viewsets.ModelViewSet):
       queryset = Book.objects.all()
       serializer_class = BookSerializer

   class LoanViewSet(viewsets.ModelViewSet):
       queryset = Loan.objects.all()
       serializer_class = LoanSerializer

הסבר:

  • ViewSets מספקים פעולות CRUD למודלים שלנו.

שלב 6: הגדרת הנתיבים (URLs)

  1. צור קובץ בשם library/urls.py והוסף:
   from django.urls import path, include
   from rest_framework import routers
   from .views import SubscriberViewSet, BookViewSet, LoanViewSet

   router = routers.DefaultRouter()
   router.register(r'subscribers', SubscriberViewSet)
   router.register(r'books', BookViewSet)
   router.register(r'loans', LoanViewSet)

   urlpatterns = [
       path('', include(router.urls)),
   ]
  1. עדכן את backend/urls.py כדי לכלול את הנתיבים של האפליקציה:
   from django.contrib import admin
   from django.urls import path, include

   urlpatterns = [
       path('admin/', admin.site.urls),
       path('api/', include('library.urls')),
   ]

שלב 7: הגדרת CORS

  1. התקן את החבילה django-cors-headers:
   pip install django-cors-headers
  1. הוסף ל-INSTALLED_APPS ב-backend/settings.py:
   INSTALLED_APPS = [
       ...
       'corsheaders',
   ]
  1. הוסף את ה-Middleware:
   MIDDLEWARE = [
       'corsheaders.middleware.CorsMiddleware',
       ...
   ]
  1. אפשר גישה מכל המקורות:
   CORS_ALLOW_ALL_ORIGINS = True

שלב 8: הרצת שרת Django

  1. הפעל את השרת:
   python manage.py runserver
  1. בדיקה: גש לדפדפן לכתובת http://localhost:8000/api/ ותראה את ה-API.

שלב 9: יצירת פרויקט React עם TypeScript

  1. בטרמינל חדש, בתיקיית הפרויקט, הרץ:
   npx create-react-app frontend --template typescript
  1. התקן את axios:
   cd frontend
   npm install axios

שלב 10: בניית ה-Frontend

  1. יצירת סוגים (Types):
  • צור תיקייה src/types.
  • צור קובץ types.ts עם התוכן: export interface Subscriber { id?: number; name: string; children_count: number; } export interface Book { id?: number; title: string; author: string; copies_available: number; } export interface Loan { id?: number; subscriber: number; book: number; loan_date?: string; }
  1. יצירת שירות API:
  • צור תיקייה src/services.
  • צור קובץ api.ts עם התוכן: import axios from 'axios'; const api = axios.create({ baseURL: 'http://localhost:8000/api/', }); export default api;
  1. יצירת רכיבים (Components):
  • צור תיקייה src/components.
  • צור רכיב BookList.tsx: import React, { useEffect, useState } from 'react'; import api from '../services/api'; import { Book } from '../types/types'; const BookList: React.FC = () => { const [books, setBooks] = useState<Book[]>([]); useEffect(() => { api.get<Book[]>('books/').then(response => { setBooks(response.data); }); }, []); return ( <div> <h2>רשימת ספרים</h2> <ul> {books.map(book => ( <li key={book.id}> {book.title} מאת {book.author} - עותקים זמינים: {book.copies_available} </li> ))} </ul> </div> ); }; export default BookList;
  1. עדכון App.tsx:
   import React from 'react';
   import BookList from './components/BookList';

   function App() {
     return (
       <div className="App">
         <h1>מערכת השאלת ספרים</h1>
         <BookList />
       </div>
     );
   }

   export default App;

שלב 11: הרצת אפליקציית React

  1. הפעל את האפליקציה:
   npm start
  1. בדיקה: גש לדפדפן לכתובת http://localhost:3000 ותראה את רשימת הספרים.

שלב 12: הוספת רכיבים נוספים

  1. רשימת מנויים (SubscriberList.tsx):
   import React, { useEffect, useState } from 'react';
   import api from '../services/api';
   import { Subscriber } from '../types/types';

   const SubscriberList: React.FC = () => {
     const [subscribers, setSubscribers] = useState<Subscriber[]>([]);

     useEffect(() => {
       api.get<Subscriber[]>('subscribers/').then(response => {
         setSubscribers(response.data);
       });
     }, []);

     return (
       <div>
         <h2>רשימת מנויים</h2>
         <ul>
           {subscribers.map(subscriber => (
             <li key={subscriber.id}>
               {subscriber.name} - מספר ילדים: {subscriber.children_count}
             </li>
           ))}
         </ul>
       </div>
     );
   };

   export default SubscriberList;
  1. הוספת מנוי חדש (AddSubscriber.tsx):
   import React, { useState } from 'react';
   import api from '../services/api';
   import { Subscriber } from '../types/types';

   const AddSubscriber: React.FC = () => {
     const [name, setName] = useState('');
     const [childrenCount, setChildrenCount] = useState(0);

     const handleSubmit = (e: React.FormEvent) => {
       e.preventDefault();
       const newSubscriber: Subscriber = { name, children_count: childrenCount };
       api.post('subscribers/', newSubscriber).then(response => {
         alert('מנוי נוסף בהצלחה!');
       });
     };

     return (
       <form onSubmit={handleSubmit}>
         <h2>הוסף מנוי</h2>
         <label>
           שם:
           <input type="text" value={name} onChange={e => setName(e.target.value)} />
         </label>
         <br />
         <label>
           מספר ילדים:
           <input type="number" value={childrenCount} onChange={e => setChildrenCount(parseInt(e.target.value))} />
         </label>
         <br />
         <button type="submit">הוסף</button>
       </form>
     );
   };

   export default AddSubscriber;
  1. עדכון App.tsx:
   import React from 'react';
   import BookList from './components/BookList';
   import SubscriberList from './components/SubscriberList';
   import AddSubscriber from './components/AddSubscriber';

   function App() {
     return (
       <div className="App">
         <h1>מערכת השאלת ספרים</h1>
         <AddSubscriber />
         <SubscriberList />
         <BookList />
       </div>
     );
   }

   export default App;

שלב 13: הוספת השאלות

  1. רכיב השאלת ספר (LoanBook.tsx):
   import React, { useState, useEffect } from 'react';
   import api from '../services/api';
   import { Subscriber, Book, Loan } from '../types/types';

   const LoanBook: React.FC = () => {
     const [subscribers, setSubscribers] = useState<Subscriber[]>([]);
     const [books, setBooks] = useState<Book[]>([]);
     const [selectedSubscriber, setSelectedSubscriber] = useState<number | null>(null);
     const [selectedBook, setSelectedBook] = useState<number | null>(null);

     useEffect(() => {
       api.get<Subscriber[]>('subscribers/').then(response => {
         setSubscribers(response.data);
       });
       api.get<Book[]>('books/').then(response => {
         setBooks(response.data);
       });
     }, []);

     const handleSubmit = (e: React.FormEvent) => {
       e.preventDefault();
       if (selectedSubscriber && selectedBook) {
         const newLoan: Loan = { subscriber: selectedSubscriber, book: selectedBook };
         api.post('loans/', newLoan).then(response => {
           alert('ספר הושאל בהצלחה!');
         }).catch(error => {
           alert('שגיאה: ' + error.response.data.detail);
         });
       }
     };

     return (
       <form onSubmit={handleSubmit}>
         <h2>השאלת ספר</h2>
         <label>
           מנוי:
           <select onChange={e => setSelectedSubscriber(parseInt(e.target.value))}>
             <option value="">בחר מנוי</option>
             {subscribers.map(subscriber => (
               <option key={subscriber.id} value={subscriber.id}>{subscriber.name}</option>
             ))}
           </select>
         </label>
         <br />
         <label>
           ספר:
           <select onChange={e => setSelectedBook(parseInt(e.target.value))}>
             <option value="">בחר ספר</option>
             {books.map(book => (
               <option key={book.id} value={book.id}>{book.title}</option>
             ))}
           </select>
         </label>
         <br />
         <button type="submit">השאל</button>
       </form>
     );
   };

   export default LoanBook;
  1. עדכון App.tsx להכללת רכיב ההשאלה:
   import React from 'react';
   import BookList from './components/BookList';
   import SubscriberList from './components/SubscriberList';
   import AddSubscriber from './components/AddSubscriber';
   import LoanBook from './components/LoanBook';

   function App() {
     return (
       <div className="App">
         <h1>מערכת השאלת ספרים</h1>
         <AddSubscriber />
         <SubscriberList />
         <BookList />
         <LoanBook 
       </div>
     );
   }

   export default App;

שלב 14: בדיקה וסיכום

  1. הפעל את שרת Django ואת אפליקציית React.
  2. בדוק את הפונקציונליות:
  • הוסף מנויים וספרים.
  • נסה להשאיל ספר למנוי.
  • ודא שהמערכת מונעת השאלה מעבר למספר המותר.

סיכום

יצרנו אפליקציית Django ו-React מלאה המדמה מערכת השאלת ספרים מהספרייה. הסברנו כל שלב בפירוט, והצגנו את הקוד המלא הנדרש לבנייה והפעלה של הפרויקט. השתמשנו ב-Django Rest Framework ליצירת API וב-React עם TypeScript ליצירת ממשק משתמש אינטראקטיבי.

הערות נוספות

  • אין צורך בידע מוקדם בתכנות, אך ייתכן שתצטרך לחפש באינטרנט למידע נוסף על כלי הפיתוח.
  • אם אתה נתקל בשגיאות, וודא שהתקנת את כל התוכנות הנדרשות ושהקוד הוזן כראוי.
  • למידה נוספת: מומלץ ללמוד את היסודות של Python, Django, JavaScript, ו-React כדי להבין לעומק את האפליקציה.

Comments

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *