Django React 1
Django React 1
React for the frontend (with high-level styling frameworks) and Django for the backend. Each
module includes assignments to solidify your understanding, with answers provided at the end
of the document. Finally, you'll tackle 10 diverse end-of-course projects to showcase your
full-stack development skills.
This course is designed to take you from a beginner to a confident full-stack developer using
React for dynamic user interfaces and Django for robust backend logic and data management.
We'll cover essential concepts, modern tools, and practical application development for
various web systems, including e-marketing, chat applications, learning management systems,
and inventory management.
Prerequisites:
Frontend: React, [Link], npm/yarn, React Router, Redux (for state management),
high-level styling frameworks (Tailwind CSS, Material UI, Chakra UI), Axios (for
API calls).
Backend: Django, Django REST Framework, PostgreSQL (or other relational
database), Django Channels (for WebSockets), Djoser (for authentication).
Version Control: Git, GitHub.
Development Environment: VS Code (recommended).
Learning Objectives:
Topics:
1. Web Development Fundamentals:
o How the web works (HTTP requests/responses).
o Frontend vs. Backend.
o Client-Server architecture.
o APIs (RESTful principles).
2. Python Refresher:
o Variables, data types, operators.
o Control flow (if/else, loops).
o Functions.
o Object-Oriented Programming (OOP) concepts.
o Virtual environments (venv).
3. Introduction to Git and GitHub:
o What is version control?
o Basic Git commands: git init, git add, git commit, git status, git
log.
o Working with remote repositories: git clone, git push, git pull.
Assignments:
Learning Objectives:
Topics:
Assignments:
Learning Objectives:
Topics:
1. Introduction to RESTful APIs:
o HTTP methods (GET, POST, PUT, DELETE).
o Statelessness.
o Resource-based URLs.
2. Django REST Framework Setup:
o Installation and configuration.
o Serializers: converting Django models to JSON and vice-versa.
o ModelSerializers.
3. DRF Views:
o APIView.
o Generic APIView and mixins.
o ViewSets and Routers.
4. Authentication and Permissions:
o Token-based authentication.
o Session authentication.
o Permission classes (IsAuthenticated, IsAdminUser,
IsAuthenticatedOrReadOnly).
o Using Djoser for user registration and authentication endpoints.
Assignments:
Learning Objectives:
Topics:
1. Introduction to React:
o Why React? (Declarative, Component-Based, Learn Once Write Anywhere).
o Virtual DOM.
o create-react-app.
2. JSX (JavaScript XML):
o Writing HTML-like code in JavaScript.
o Embedding expressions.
3. React Components:
o Functional components vs. Class components (focus on functional).
o Props: passing data down the component tree.
o State and useState hook: managing component-specific data.
o Lifecycle methods and useEffect hook.
4. Event Handling:
o Handling user interactions (clicks, input changes).
5. Forms in React:
o Controlled components.
o Handling form submissions.
6. React Router:
o Setting up client-side routing.
o BrowserRouter, Routes, Route, Link, useNavigate.
Assignments:
Learning Objectives:
Assignments:
Learning Objectives:
Product Management: Add, edit, delete products with details (name, description,
price, stock, images).
User Authentication: Registration, login, logout, password reset.
Shopping Cart: Add/remove items, update quantities.
Checkout Process: Order summary, payment integration (mock or simplified),
shipping details.
Order History: Users can view their past orders.
Search and Filtering: Search products by name, category, price.
Admin Dashboard: For managing products, users, and orders.
Assignments:
Learning Objectives:
Assignments:
Learning Objectives:
Course Management: Create, edit, publish courses with lessons and topics.
User Roles: Students and Instructors.
Enrollment: Students can enroll in courses.
Lesson Viewing: Display course content (text, video links).
Quizzes/Assignments: Create, take, and grade quizzes/assignments.
Progress Tracking: Students can see their progress in courses.
Instructor Dashboard: Manage their courses, view student progress.
Assignments:
Learning Objectives:
Item Management: Add, edit, delete inventory items (name, SKU, quantity, price,
location).
Stock Tracking: Real-time updates of stock levels.
Supplier Management: Store supplier information.
Order Management (Purchase/Sales): Create and track purchase orders (incoming
stock) and sales orders (outgoing stock).
Inventory Alerts: Low stock notifications.
Reporting: Generate reports on current stock, sales, and purchase history.
Multi-location Support: (Optional, advanced) Manage inventory across multiple
warehouses.
Assignments:
Learning Objectives:
Topics:
1. Deployment Strategies:
o Django Deployment:
Gunicorn/uWSGI as WSGI server.
Nginx as a reverse proxy.
Collecting static files.
Environment variables.
Brief overview of cloud platforms (Heroku, AWS, DigitalOcean).
o React Deployment:
Building for production (npm run build).
Serving static files.
Deployment to Netlify, Vercel, or integrating with Django's Nginx
setup.
2. Security Best Practices:
o Django security features (CSRF, XSS protection).
o Securing API endpoints.
o Handling sensitive data.
o CORS configuration.
3. Performance Optimization:
o Database indexing.
o Caching (Django caching, React memoization).
o Lazy loading React components.
4. Code Organization and Maintainability:
o Modular Django apps.
o Reusable React components.
o Consistent naming conventions.
o Testing strategies (unit, integration - brief overview).
Assignments:
These projects are designed to integrate the knowledge gained throughout the course. For
each project, focus on building a minimal viable product (MVP) with core functionalities,
then consider adding optional advanced features.
Django Backend:
o Well-defined models with appropriate relationships.
o DRF APIs for all necessary CRUD (Create, Read, Update, Delete) operations.
o User authentication (registration, login, logout) using Djoser or similar.
o Proper URL routing.
o Sensible database migrations.
React Frontend:
o Component-based architecture.
o State management (Redux Toolkit recommended for complex state).
o API integration with Axios.
o Client-side routing with React Router.
o High-level styling framework applied consistently.
o Responsive design.
o Clear and intuitive user interface.
Version Control: Project hosted on GitHub with clear commit history.
Documentation: A [Link] file explaining how to set up and run the project, and
any key architectural decisions.
Project 1: Advanced Blog Platform
Core Features:
o User authentication (register, login, logout, password reset).
o Create, read, update, delete blog posts.
o Add comments to posts.
o Like/dislike posts (basic).
o User profiles displaying their posts and comments.
o Search functionality for posts.
Advanced Features (Optional):
o Rich text editor for post content.
o Tags/categories for posts.
o Draft posts functionality.
o Image uploads for posts.
o Admin dashboard for managing all content.
Core Features:
o Product catalog with categories and search.
o Product detail pages with images, descriptions, and "Add to Cart" button.
o Shopping cart (add, remove, update quantities).
o User registration and login.
o Checkout process with mock payment.
o Order history for users.
o Basic admin panel to manage products and view orders.
Advanced Features (Optional):
o Real payment gateway integration (e.g., Stripe, PayPal - for learning purposes,
not production).
o User reviews and ratings for products.
o Wishlist functionality.
o Shipping address management.
o Inventory management integration (low stock alerts).
Core Features:
o User authentication.
o Create and join "rooms" or "boards."
o Real-time drawing and erasing functionality (lines, shapes) synchronized
across connected users in the same room.
o Use Django Channels for WebSocket communication.
Advanced Features (Optional):
o Different colors and brush sizes.
o Text tool.
o Saving and loading drawings.
o Undo/redo functionality.
o User cursors visible to others.
Project 4: Online Learning Platform with Course Progress
Core Features:
o Two user roles: Student and Instructor.
o Instructors can create courses, add lessons (text, video links), and
assignments/quizzes.
o Students can enroll in courses, view lessons, and submit assignments/take
quizzes.
o Track student progress within courses.
o Instructor dashboard to view enrolled students and their progress.
Advanced Features (Optional):
o Course discussion forums.
o Certificates upon course completion.
o Grading system for assignments.
o Live Q&A sessions (using chat functionality).
o Rating/review system for courses.
Core Features:
o Manage inventory items (name, SKU, quantity, location, description).
o Record incoming (purchase orders) and outgoing (sales orders) stock.
o Update stock levels automatically based on orders.
o Generate low stock alerts.
o Supplier management.
o Basic reporting (current stock levels, recent movements).
Advanced Features (Optional):
o Integration with a barcode/QR code scanner (simulated or real).
o Multi-warehouse/location management.
o Demand forecasting (simple).
o Audit trails for all inventory changes.
o User roles with different permissions.
Core Features:
o User roles: Job Seeker and Employer.
o Employers can post job listings (title, description, requirements, location,
salary range).
o Job seekers can browse, search, and filter job listings.
o Job seekers can apply to jobs (simple form with resume upload - mock).
o Employer dashboard to manage their job postings and view applications.
Advanced Features (Optional):
o User profiles for job seekers (skills, experience).
o Employer profiles.
o Notifications for new relevant jobs.
o Application tracking system for employers.
o Integrated messaging between job seekers and employers.
Core Features:
o User authentication.
o Users can create posts (text, optional image upload).
o Users can like/unlike posts.
o Users can comment on posts.
o A main feed displaying posts from all users.
o User profiles displaying their posts.
Advanced Features (Optional):
o Follow/unfollow users.
o Notifications (e.g., when someone likes/comments on your post).
o Hashtags and trending topics.
o Real-time updates for likes/comments (using WebSockets).
Core Features:
o User authentication.
o Create events (name, date, time, location, description, ticket price, capacity).
o Browse and search for events.
o Register for events/purchase tickets (mock payment).
o View registered/purchased events.
o Admin dashboard to manage events and view attendees.
Advanced Features (Optional):
o QR code generation for tickets.
o Event categories.
o Attendee check-in functionality.
o Email notifications for event registration.
Core Features:
o User authentication.
o Users can create and share recipes (name, ingredients, instructions, categories,
cooking time).
o Browse and search for recipes.
o Rate and review recipes.
o User profiles displaying their shared recipes.
Advanced Features (Optional):
o Save recipes to a "favorites" list.
o Ingredient search (find recipes based on ingredients you have).
o Meal planning functionality.
o Nutritional information integration.
o Video recipes.
Assignments Answers
Python
name = input("Enter your name: ")
age_str = input("Enter your age: ")
try:
age = int(age_str)
current_year = 2025 # Assuming current year for calculation
year_turns_100 = current_year + (100 - age)
print(f"Hello, {name}! You are {age} years old.")
print(f"You will turn 100 in the year {year_turns_100}.")
except ValueError:
print("Invalid age entered. Please enter a number.")
Bash
Python
INSTALLED_APPS = [
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'blog', # Add this line
]
Python
class Post([Link]):
title = [Link](max_length=200)
content = [Link]()
author = [Link](User, on_delete=[Link])
published_date = [Link](auto_now_add=True)
def __str__(self):
return [Link]
Bash
Python
[Link](Post)
Bash
Python
def post_list(request):
posts = [Link]().order_by('-published_date')
context = {'posts': posts}
return render(request, 'blog/post_list.html', context)
Python
urlpatterns = [
path('posts/', views.post_list, name='post_list'),
]
Python
urlpatterns = [
path('admin/', [Link]),
path('blog/', include('[Link]')), # Include your app's URLs
]
10. Create Template (BlogSite/blog/templates/blog/post_list.html):
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>Blog Posts</title>
</head>
<body>
<h1>All Blog Posts</h1>
{% if posts %}
<ul>
{% for post in posts %}
<li>
<h2>{{ [Link] }}</h2>
<p>By {{ [Link] }} on {{
post.published_date }}</p>
<p>{{ [Link]|truncatewords:50 }}</p>
</li>
{% endfor %}
</ul>
{% else %}
<p>No blog posts found.</p>
{% endif %}
</body>
</html>
Python
class Post([Link]):
# ... (existing Post model) ...
class Profile([Link]):
user = [Link](User, on_delete=[Link])
bio = [Link](blank=True, null=True)
profile_picture = [Link](upload_to='profile_pics/',
blank=True, null=True)
def __str__(self):
return [Link]
Python
[Link](Post)
[Link](Profile)
Now, in the Django Admin, you'll see a "Profiles" section where you can create and
manage user profiles. Each User object will have a link to create/edit their associated
Profile.
1. Install DRF:
Bash
Python
INSTALLED_APPS = [
# ... existing apps ...
'rest_framework', # Add this
'blog',
]
Python
class PostSerializer([Link]):
author = [Link](source='[Link]') #
Display author's username
class Meta:
model = Post
fields = ['id', 'title', 'content', 'author',
'published_date']
read_only_fields = ['author', 'published_date'] # Prevent
direct modification of these fields
Python
class PostListCreateAPIView([Link]):
queryset = [Link]().order_by('-published_date')
serializer_class = PostSerializer
permission_classes = [IsAuthenticatedOrReadOnly] # Allow read for
anyone, create for authenticated
class PostDetailAPIView([Link]):
queryset = [Link]()
serializer_class = PostSerializer
permission_classes = [IsAuthenticatedOrReadOnly] # Allow read for
anyone, update/delete for authenticated
Python
urlpatterns = [
path('posts/', views.post_list, name='post_list'), # Keep
existing for template view
path('api/posts/', PostListCreateAPIView.as_view(),
name='api_post_list_create'),
path('api/posts/<int:pk>/', PostDetailAPIView.as_view(),
name='api_post_detail'),
]
6. Test your API:
o Run python [Link] runserver.
o Open Postman or Insomnia.
o GET [Link] Should return a list of
your posts.
o POST [Link]
Set Content-Type: application/json.
Body: {"title": "My New API Post", "content": "This is
content from the API."}
If not logged in, it should give a permission error.
To test authentication, you'll need a user token (see Assignment 3.2).
Once authenticated, you can send the Authorization: Token
<your_token> header.
1. Install Djoser:
Bash
Python
INSTALLED_APPS = [
# ... existing apps ...
'rest_framework',
'rest_framework.authtoken', # For token authentication
'djoser', # For user management endpoints
'blog',
]
Python
Bash
Bash
2. src/[Link]:
JavaScript
function App() {
const [count, setCount] = useState(0);
return (
<div className="App">
<header className="App-header">
<h1>Simple Counter</h1>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</header>
</div>
);
}
Bash
npm start
1. src/[Link]:
JavaScript
function TodoList() {
const [todos, setTodos] = useState([]);
const [newTodo, setNewTodo] = useState('');
return (
<div>
<h1>My To-Do List</h1>
<input
type="text"
value={newTodo}
onChange={(e) => setNewTodo([Link])}
placeholder="Add a new todo..."
/>
<button onClick={addTodo}>Add Todo</button>
<ul>
{[Link](todo => (
<li key={[Link]} style={{ textDecoration: [Link] ?
'line-through' : 'none' }}>
{[Link]}
<button onClick={() => toggleComplete([Link])} style={{
marginLeft: '10px' }}>
{[Link] ? 'Undo' : 'Complete'}
</button>
</li>
))}
</ul>
</div>
);
}
JavaScript
function App() {
return (
<div className="App">
<header className="App-header">
<TodoList />
</header>
</div>
);
}
2. src/[Link]:
JavaScript
function App() {
return (
<Router>
<div className="App">
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
</nav>
<header className="App-header">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</header>
</div>
</Router>
);
}
Assignment 5.1: Blog Frontend with API Integration - Completion (Conceptual Outline)
This assignment involves connecting your React frontend to the Django Blog API
from Module 3.
Bash
2. src/app/[Link]:
JavaScript
3. src/features/posts/[Link]:
JavaScript
JavaScript
JavaScript
function PostList() {
const dispatch = useDispatch();
const posts = useSelector((state) => [Link]);
const postStatus = useSelector((state) => [Link]);
const error = useSelector((state) => [Link]);
const authToken = useSelector((state) => [Link]); // Get
token from auth slice
useEffect(() => {
if (postStatus === 'idle') {
dispatch(fetchPosts());
}
}, [postStatus, dispatch]);
return (
<div>
<h1>Blog Posts</h1>
<Link to="/posts/new">Create New Post</Link>
<ul>
{[Link]((post) => (
<li key={[Link]}>
<Link to={`/posts/${[Link]}`}>
<h2>{[Link]}</h2>
</Link>
<p>By {[Link]} on {new
Date(post.published_date).toLocaleDateString()}</p>
{authToken && ( // Only show delete if user is
authenticated
<button onClick={() =>
handleDelete([Link])}>Delete</button>
)}
</li>
))}
</ul>
</div>
);
}
Assignment 5.3: Styling the Blog - Completion (Conceptual Outline for Tailwind CSS)
Bash
2. Configure [Link]:
JavaScript
CSS
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Add any custom global styles here */
body {
font-family: sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f4;
}
JavaScript
Python
class Category([Link]):
name = [Link](max_length=100, unique=True)
description = [Link](blank=True, null=True)
def __str__(self):
return [Link]
class Product([Link]):
name = [Link](max_length=200)
description = [Link]()
price = [Link](max_digits=10, decimal_places=2)
stock = [Link](default=0)
image = [Link](upload_to='product_images/',
blank=True, null=True)
category = [Link](Category, on_delete=models.SET_NULL,
null=True, blank=True)
created_at = [Link](auto_now_add=True)
updated_at = [Link](auto_now=True)
def __str__(self):
return [Link]
class Order([Link]):
user = [Link](User, on_delete=[Link])
created_at = [Link](auto_now_add=True)
updated_at = [Link](auto_now=True)
is_paid = [Link](default=False)
# Add shipping address fields, total price, etc.
def __str__(self):
return f"Order {[Link]} by {[Link]}"
class OrderItem([Link]):
order = [Link](Order, on_delete=[Link],
related_name='items')
product = [Link](Product, on_delete=models.SET_NULL,
null=True)
quantity = [Link](default=1)
price = [Link](max_digits=10, decimal_places=2) #
Price at time of order
def __str__(self):
return f"{[Link]} of {[Link]}"
2. Serializers (ecommerce_app/[Link]):
Python
class CategorySerializer([Link]):
class Meta:
model = Category
fields = '__all__'
class ProductSerializer([Link]):
category_name = [Link](source='[Link]',
read_only=True)
class Meta:
model = Product
fields = ['id', 'name', 'description', 'price', 'stock',
'image', 'category', 'category_name', 'created_at', 'updated_at']
class OrderItemSerializer([Link]):
product_name = [Link](source='[Link]',
read_only=True)
class Meta:
model = OrderItem
fields = ['id', 'product', 'product_name', 'quantity',
'price']
class OrderSerializer([Link]):
items = OrderItemSerializer(many=True, read_only=True) # Nested
serializer for order items
user_username = [Link](source='[Link]',
read_only=True)
class Meta:
model = Order
fields = ['id', 'user', 'user_username', 'created_at',
'updated_at', 'is_paid', 'items']
read_only_fields = ['user']
3. Views (ecommerce_app/[Link]):
Python
class ProductListCreateAPIView([Link]):
queryset = [Link]().select_related('category') #
Optimize query
serializer_class = ProductSerializer
parser_classes = [MultiPartParser, FormParser] # Required for
image uploads
permission_classes = [[Link]] #
Allow anyone to view, authenticated to create
class ProductDetailAPIView([Link]):
queryset = [Link]()
serializer_class = ProductSerializer
parser_classes = [MultiPartParser, FormParser]
permission_classes = [[Link]]
class CategoryListCreateAPIView([Link]):
queryset = [Link]()
serializer_class = CategorySerializer
permission_classes = [[Link]]
class CategoryDetailAPIView([Link]):
queryset = [Link]()
serializer_class = CategorySerializer
permission_classes = [[Link]]
class OrderListCreateAPIView([Link]):
queryset = [Link]()
serializer_class = OrderSerializer
permission_classes = [[Link]]
def get_queryset(self):
# Users can only see their own orders
return [Link](user=[Link])
class OrderDetailAPIView([Link]):
queryset = [Link]()
serializer_class = OrderSerializer
permission_classes = [[Link]]
def get_queryset(self):
return [Link](user=[Link])
4. URLs (ecommerce_app/[Link]):
Python
urlpatterns = [
path('products/', ProductListCreateAPIView.as_view(),
name='product-list-create'),
path('products/<int:pk>/', ProductDetailAPIView.as_view(),
name='product-detail'),
path('categories/', CategoryListCreateAPIView.as_view(),
name='category-list-create'),
path('categories/<int:pk>/', CategoryDetailAPIView.as_view(),
name='category-detail'),
path('orders/', OrderListCreateAPIView.as_view(), name='order-
list-create'),
path('orders/<int:pk>/', OrderDetailAPIView.as_view(),
name='order-detail'),
]
Python
Python
urlpatterns = [
# ... existing paths ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
1. src/components/[Link]:
o Fetch products from [Link]
o Display product cards (image, name, price) using a grid layout.
o Implement search input and category dropdown filters.
o Each product card links to its detail page.
2. src/components/[Link]:
o Fetch product details based on id from URL.
o Display product image, name, description, price, stock.
o "Add to Cart" button.
JavaScript
if (existingItem) {
[Link]++;
} else {
[Link]({ ...newItem, quantity: 1 });
}
[Link]++;
[Link] += [Link];
},
removeItemFromCart: (state, action) => {
const id = [Link];
const existingItem = [Link](item => [Link]
=== id);
if (existingItem) {
[Link]--;
[Link] -= [Link];
if ([Link] === 1) {
[Link] = [Link](item => [Link] !==
id);
} else {
[Link]--;
}
}
},
// Optionally, a clearCart reducer
},
});
2. src/components/[Link]:
o Import useDispatch and addItemToCart.
o On "Add to Cart" button click, dispatch(addItemToCart({ productId:
[Link], name: [Link], price: [Link], image:
[Link] })).
3. src/components/[Link]:
o Import useSelector to get [Link], [Link],
[Link].
o Display a list of items in the cart with quantity controls and subtotal.
o A "Checkout" button (which will lead to a new module's assignment).
Module 7: Developing a Chat Application
Python
INSTALLED_APPS = [
# ...
'channels',
'chat_app', # Your new chat app
]
ASGI_APPLICATION = '[Link]' # Or
your_project_name.[Link]
Python
import os
from [Link] import get_asgi_application
from [Link] import ProtocolTypeRouter, URLRouter
from [Link] import AuthMiddlewareStack # For authenticated
websockets
import chat_app.routing # Assuming your chat app is named 'chat_app'
[Link]('DJANGO_SETTINGS_MODULE', '[Link]')
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
chat_app.routing.websocket_urlpatterns
)
),
})
Python
def __str__(self):
return [Link]
class Message([Link]):
room = [Link](ChatRoom, on_delete=[Link],
related_name='messages')
sender = [Link](User, on_delete=[Link])
content = [Link]()
timestamp = [Link](auto_now_add=True)
class Meta:
ordering = ['timestamp']
def __str__(self):
return f"{[Link]}: {[Link][:50]}"
5. Serializers (chat_app/[Link]):
Python
class MessageSerializer([Link]):
sender_username = [Link](source='[Link]',
read_only=True)
class Meta:
model = Message
fields = ['id', 'room', 'sender', 'sender_username',
'content', 'timestamp']
read_only_fields = ['sender', 'timestamp']
class ChatRoomSerializer([Link]):
class Meta:
model = ChatRoom
fields = '__all__'
6. Consumers (chat_app/[Link]):
Python
import json
from [Link] import AsyncWebsocketConsumer
from [Link] import User
from .models import Message, ChatRoom
from [Link] import sync_to_async
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name =
[Link]['url_route']['kwargs']['room_name']
self.room_group_name = f"chat_{self.room_name}"
if not sender_id:
await [Link](text_data=[Link]({'error':
'Authentication required'}))
return
@sync_to_async
def save_message(self, sender_id, room_name, content):
user = [Link](id=sender_id)
room, created =
[Link].get_or_create(name=room_name)
[Link](sender=user, room=room,
content=content)
7. Routing (chat_app/[Link]):
Python
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<room_name>\w+)/$',
[Link].as_asgi()),
]
8. API Views for ChatRooms and Messages (Optional, for initial fetching of
history): Add ChatRoomListCreateAPIView and MessageListAPIView (filtered by
room) using DRF generics to chat_app/[Link].
1. src/components/[Link]:
JavaScript
function ChatRoom() {
const { roomName } = useParams();
const [messages, setMessages] = useState([]);
const [inputMessage, setInputMessage] = useState('');
const ws = useRef(null);
const authToken = useSelector((state) => [Link]); //
Assuming auth token is in Redux state
const messagesEndRef = useRef(null); // For auto-scrolling
useEffect(() => {
// Fetch historical messages from your Django API here if needed
//
[Link](`[Link]
`, { headers: { Authorization: `Token ${authToken}` } })
// .then(res => setMessages([Link]));
// WebSocket connection
[Link] = new
WebSocket(`[Link]
}`); // Pass token as query param
useEffect(() => {
[Link]?.scrollIntoView({ behavior: "smooth" });
}, [messages]); // Scroll to bottom when messages change
return (
<div className="flex flex-col h-screen max-w-lg mx-auto border
rounded-lg shadow-lg">
<h1 className="text-2xl font-bold p-4 bg-blue-600 text-white
rounded-t-lg">Chat Room: {roomName}</h1>
<div className="flex-grow p-4 overflow-y-auto space-y-2">
{[Link]((msg, index) => (
<div key={index} className={`flex ${[Link] ===
'current_user_username' ? 'justify-end' : 'justify-start'}`}>
<div className={`p-2 rounded-lg ${[Link] ===
'current_user_username' ? 'bg-blue-200' : 'bg-gray-200'}`}>
<p className="font-semibold">{[Link]}</p>
<p>{[Link]}</p>
<span className="text-xs text-gray-500">{{ new
Date([Link]).toLocaleTimeString() }}</span>
</div>
</div>
))}
<div ref={messagesEndRef} />
</div>
<div className="p-4 border-t flex">
<input
type="text"
value={inputMessage}
onChange={(e) => setInputMessage([Link])}
onKeyPress={(e) => [Link] === 'Enter' && sendMessage()}
placeholder="Type your message..."
className="flex-grow border rounded-l-lg p-2 focus:outline-
none focus:ring-2 focus:ring-blue-500"
/>
<button
onClick={sendMessage}
className="bg-blue-500 hover:bg-blue-700 text-white font-
bold py-2 px-4 rounded-r-lg"
>
Send
</button>
</div>
</div>
);
}
export default ChatRoom;
o Note: Passing the authToken via query parameter is a common way for
WebSocket authentication in Channels. In your ChatConsumer, you'd typically
extract and validate this token to associate the WebSocket connection with an
authenticated user. You'd replace 'current_user_username' with the actual
authenticated username.
o Add routing in src/[Link] for /chat/:roomName.
1. Models (lms_app/[Link]):
Python
class Course([Link]):
title = [Link](max_length=255)
description = [Link]()
instructor = [Link](User, on_delete=[Link],
related_name='taught_courses')
is_published = [Link](default=False)
created_at = [Link](auto_now_add=True)
updated_at = [Link](auto_now=True)
def __str__(self):
return [Link]
class Lesson([Link]):
course = [Link](Course, on_delete=[Link],
related_name='lessons')
title = [Link](max_length=255)
content = [Link]() # Markdown or simple text
video_url = [Link](blank=True, null=True)
order = [Link](default=0) # For ordering
lessons
class Meta:
ordering = ['order']
def __str__(self):
return f"{[Link]} - {[Link]}"
class Quiz([Link]):
course = [Link](Course, on_delete=[Link],
related_name='quiz')
title = [Link](max_length=255)
description = [Link](blank=True, null=True)
def __str__(self):
return f"Quiz for {[Link]}"
class Question([Link]):
quiz = [Link](Quiz, on_delete=[Link],
related_name='questions')
text = [Link]()
# Add question type (e.g., 'multiple_choice', 'text_answer')
def __str__(self):
return [Link][:50]
class Option([Link]):
question = [Link](Question, on_delete=[Link],
related_name='options')
text = [Link](max_length=255)
is_correct = [Link](default=False)
def __str__(self):
return [Link]
class Enrollment([Link]):
student = [Link](User, on_delete=[Link],
related_name='enrollments')
course = [Link](Course, on_delete=[Link],
related_name='enrollments')
date_enrolled = [Link](auto_now_add=True)
completed_lessons = [Link](Lesson, blank=True)
# Optional: completion_date, progress_percentage
class Meta:
unique_together = ('student', 'course') # A student can
enroll in a course only once
def __str__(self):
return f"{[Link]} enrolled in
{[Link]}"
class Submission([Link]):
enrollment = [Link](Enrollment,
on_delete=[Link])
quiz = [Link](Quiz, on_delete=[Link],
null=True, blank=True)
# For assignments
# assignment = [Link](Assignment,
on_delete=[Link], null=True, blank=True)
submitted_at = [Link](auto_now_add=True)
score = [Link](max_digits=5, decimal_places=2,
null=True, blank=True)
# Add answer field for text answers, or a JSON field for quiz
answers
def __str__(self):
return f"Submission by {[Link]} for
{[Link] if [Link] else 'Assignment'}"
2. Serializers and Views: Create DRF serializers and generics views (ListCreate,
RetrieveUpdateDestroy) for Course, Lesson, Quiz, Question, Option, Enrollment,
Submission. Ensure proper permissions (e.g., only instructors can create/update
courses, students can create enrollments and submissions).
Assignment 8.2: Course Listing and Enrollment Frontend - Completion (Conceptual
Outline)
1. src/components/[Link]:
o Fetch courses from Django API.
o Display each course with title, description, instructor.
o "View Details" button linking to CourseDetail page.
o "Enroll" button for authenticated students.
2. src/components/[Link]:
o Fetch course details.
o Display lessons (list of titles, linking to LessonView).
o Enrollment button/status.
3. src/components/[Link]:
o Fetch Enrollment objects for the authenticated user.
o Display courses the user is enrolled in.
o Links to CourseDetail for enrolled courses.
o (Optional) Display basic progress.
1. src/components/[Link]:
o Fetch quiz details and questions/options for a given quiz_id.
o Display questions with their options (e.g., radio buttons for multiple choice).
o useState to store selected answers.
o "Submit Quiz" button.
o On submit, send answers to a Django API endpoint (Submission creation).
o (Optional) Display score/feedback from the backend response.
Assignment 9.1: Inventory Backend Models & API - Completion (Conceptual Outline)
1. Models (inventory_app/[Link]):
Python
class Item([Link]):
name = [Link](max_length=255)
sku = [Link](max_length=100, unique=True)
description = [Link](blank=True, null=True)
quantity = [Link](default=0)
price = [Link](max_digits=10, decimal_places=2)
location = [Link](max_length=255, blank=True,
null=True) # e.g., "Warehouse A, Shelf 3"
created_at = [Link](auto_now_add=True)
updated_at = [Link](auto_now=True)
def __str__(self):
return [Link]
class Supplier([Link]):
name = [Link](max_length=255)
contact_person = [Link](max_length=255, blank=True,
null=True)
email = [Link](blank=True, null=True)
phone = [Link](max_length=20, blank=True, null=True)
address = [Link](blank=True, null=True)
def __str__(self):
return [Link]
class PurchaseOrder([Link]):
supplier = [Link](Supplier, on_delete=models.SET_NULL,
null=True, blank=True)
order_date = [Link](auto_now_add=True)
expected_delivery_date = [Link](null=True, blank=True)
is_received = [Link](default=False)
# total_amount = [Link](max_digits=10,
decimal_places=2, default=0.00) # Can be calculated
def __str__(self):
return f"PO-{[Link]} from {[Link] if
[Link] else 'N/A'}"
class PurchaseOrderItem([Link]):
order = [Link](PurchaseOrder,
on_delete=[Link], related_name='items')
item = [Link](Item, on_delete=[Link])
quantity = [Link]()
unit_price = [Link](max_digits=10, decimal_places=2)
def __str__(self):
return f"{[Link]} of {[Link]} for PO-
{[Link]}"
class SaleOrder([Link]):
customer_name = [Link](max_length=255, blank=True,
null=True) # Or ForeignKey to User
order_date = [Link](auto_now_add=True)
is_fulfilled = [Link](default=False)
def __str__(self):
return f"SO-{[Link]} for {self.customer_name if
self.customer_name else 'N/A'}"
class SaleOrderItem([Link]):
order = [Link](SaleOrder, on_delete=[Link],
related_name='items')
item = [Link](Item, on_delete=[Link])
quantity = [Link]()
unit_price = [Link](max_digits=10, decimal_places=2)
def __str__(self):
return f"{[Link]} of {[Link]} for SO-
{[Link]}"
2. Serializers and Views: Create DRF serializers and generics views for all models.
o Inventory Update Logic (in views/serializers):
When PurchaseOrderItem is created/updated, increment
[Link].
When SaleOrderItem is created/updated, decrement [Link].
Add validation to prevent negative stock.
o Permission: Typically, only authenticated staff/admin users should manage
inventory.
1. src/components/[Link]:
o Fetch Item data from your Django API.
o Display a table/list of items with Name, SKU, Quantity, Price, Location.
o "Edit" and "Delete" buttons for each item (requires authentication).
o Input field for manual quantity adjustment (e.g., a "Restock" button next to
each item that opens a modal to add/subtract).
2. src/components/[Link]:
o A form to add new Items (Name, SKU, Quantity, Price, Location).
o Submission sends POST request to API.
1. src/components/[Link]:
o Dropdown to select an existing Supplier. Fetch suppliers from API.
o Dynamic fields to add PurchaseOrderItems:
Dropdown to select an Item. Fetch items from API.
Input for quantity.
Input for unit_price.
"Add Item to Order" button to add to local form state.
o Display a summary of items added to the current order.
o "Submit Purchase Order" button:
On click, send a POST request to your PurchaseOrder API endpoint.
The payload should include the supplier_id and a list of items (each
with item_id, quantity, unit_price). Your Django view will need to
process this to create PurchaseOrder and PurchaseOrderItems, then
update Item quantities.
Python
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
2. Run collectstatic:
Bash
This gathers all static files into the STATIC_ROOT directory, ready to be served by a
web server like Nginx.
Bash
This creates a build folder (or dist depending on setup) containing the optimized,
production-ready React application files.
Deployment Steps:
1. Backend (Django):
o Requirements: Create [Link] (pip freeze >
[Link]).
o Procfile: Create a Procfile in the root of your Django project:
o web: gunicorn [Link] --log-file -
Sources
Demandez à Gemini de créer un rapport de recherche détaillé sur ce sujet