Issue
On my app, I can add new courses from Django Admin Panel Only by using the model in Django Admin Panel.
Picture 1 - Django Admin Panel
Picture 2 - Adding New Course from Admin Panel
I want to automate this whole process. I want to create a form where users can fill out the form and submit their Course using UI. And That course will automatically be added to the Courses. So, to achieve my goal, what are the necessary steps I should take? For a better understanding of my problem here is the GitHub repo link to my project.
GitHub Repo of My Project
Tecah.html form for adding new Course:
{% extends 'layouts/base.html' %}
{% load static %}
{% load humanize %}
{% block content %}
<div class="container">
<br>
<h1>Teach on Hogwarts</h1>
<br>
{% if user.is_authenticated %}
<h3 align="center">
<i class="fa-solid fa-door-open"></i>
Welcome
<i class="fa-solid fa-door-open"></i>
</h3><br>
<img src="{% static 'images/info_banner.png' %}" alt="info" width="770" height="200" style="vertical-align:middle;margin:auto auto"/>
<br>
<div class="container">
<form class="form-horizontal" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="mb-3">
<label for="formGroupExampleInput" class="form-label">Course Title</label>
<input name="title" type="text" class="form-control" id="f1" placeholder="Enter the course title" required>
</div>
<div class="mb-3">
<label>CATEGORY</label>
<select name="category" class="form-control" id="f2" required>
<option value="GD">Graphis & Design</option>
<option value="WD">Web & Mobile Development</option>
<option value="BE">Basic Education</option>
<option value="CS">Computer Science</option>
<option value="PT">Programming & Tech</option>
</select>
</div>
<div class="mb-3">
<label for="formGroupExampleInput2" class="form-label" >Short Description</label>
<input name="short_description" required type="text" class="form-control" id="f3" placeholder="Write a short Description">
</div>
<div class="form-group">
<label for="exampleFormControlTextarea1" >Description</label>
<textarea name="description" class="form-control" id="f4" rows="3" required></textarea>
</div>
<div class="mb-3">
<label for="formGroupExampleInput2" class="form-label">Outcome</label>
<input name="outcome" type="text" class="form-control" id="f5" placeholder="">
</div>
<div class="mb-3">
<label for="formGroupExampleInput2" class="form-label">Requirements</label>
<input name="requirements" type="text" class="form-control" id="f6" placeholder="Write about prerequisites">
</div>
<div class="mb-3">
<label for="formGroupExampleInput2" class="form-label" >Language</label>
<input name="language" type="text" class="form-control" required id="f7" placeholder="Which Language is used for this course?">
</div>
<div class="mb-3">
<label>PRICE ($)</label>
<input type="number" id="f8" required class="form-control" value="19.99" name="price">
</div>
<div class="mb-3">
<label for="formGroupExampleInput2" class="form-label">Level</label>
<input name="level" type="text" class="form-control" id="f9" placeholder="Difficulty of this course?">
</div>
<div class="mb-3">
<label for="formGroupExampleInput2" class="form-label">Video URL</label>
<input name="url" type="text" required class="form-control" id="f10" placeholder="Enter the URL of this course.">
</div>
<div class="mb-3">
<label>Thumbnail</label>
<input type="file" required class="form-control" name="photo">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
{% else %}
<p align="center">
<i class="fa-solid fa-circle-info" align="center"></i><br>
Please login first to access this feature!!!
</p><br>
{% endif %}
<br>
</div>
{% endblock %}
Forms.py (I created this manually):
from django import forms
from django.contrib.auth import authenticate
from django.contrib.auth.forms import UserCreationForm
from .models import Category,Course,Lesson
Models.py:
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from django.utils.text import slugify
from django.utils.timezone import now
from accounts.models import User
class Category(models.Model):
title = models.CharField(max_length=50)
slug = models.SlugField(max_length=200, unique=True)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Category, self).save(*args, **kwargs)
class Course(models.Model):
title = models.CharField(max_length=200)
user = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
slug = models.SlugField(max_length=200, unique=True, primary_key=True, auto_created=False)
short_description = models.TextField(blank=False, max_length=60)
description = models.TextField(blank=False)
outcome = models.CharField(max_length=200)
requirements = models.CharField(max_length=200)
language = models.CharField(max_length=200)
price = models.FloatField(validators=[MinValueValidator(9.99)])
level = models.CharField(max_length=20)
thumbnail = models.ImageField(upload_to='thumbnails/')
video_url = models.CharField(max_length=100)
is_published = models.BooleanField(default=True)
created_at = models.DateTimeField(default=now)
updated_at = models.DateTimeField(default=now)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Course, self).save(*args, **kwargs)
class Lesson(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='lessons')
title = models.CharField(max_length=100)
duration = models.FloatField(validators=[MinValueValidator(0.30), MaxValueValidator(30.00)])
video_url = models.CharField(max_length=100)
created_at = models.DateTimeField(default=now)
updated_at = models.DateTimeField(default=now)
def __str__(self):
return self.title
urls.py:
from django.urls import path
from .views import *
app_name = 'courses'
urlpatterns = [
path('courses/<slug:slug>', CourseDetailView.as_view(), name='course-details'),
path('courses/<slug:slug>/category', CoursesByCategoryListView.as_view(), name='course-by-category'),
]
Solution
You should use ModelForm
, in the following way for saving the Course
model instances.
tecah.html
{% extends 'layouts/base.html' %}
{% load static %}
{% load humanize %}
{% block internalStyle %}
<style>
.green{
color:green;
font-size:1.2rem;
}
</style>
{% endblock internalStyle %}
{% block content %}
<div class="container">
<br>
<h1>Teach on Hogwarts</h1>
<br>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% if user.is_authenticated %}
<h3 align="center">
<i class="fa-solid fa-door-open"></i>
Welcome
<i class="fa-solid fa-door-open"></i>
</h3><br>
<img src="{% static 'images/info_banner.png' %}" alt="info" width="770" height="200" style="vertical-align:middle;margin:auto auto"/>
<br>
<div class="container">
<form class="form-horizontal" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="Save">
</form>
</div>
{% else %}
<p align="center">
<i class="fa-solid fa-circle-info" align="center"></i><br>
Please login first to access this feature!!!
</p><br>
{% endif %}
<br>
</div>
{% endblock %}
forms.py
from django import forms
from .models import Course
class CourseForm(forms.ModelForm):
class Meta:
model = Course
fields = ['title', 'category', 'short_description', 'description', 'video_url',
'outcome', 'requirements', 'language', 'price', 'level', 'thumbnail']
views.py
from django.http import Http404
from django.shortcuts import render
from django.views.generic import DetailView, ListView
from django.shortcuts import redirect
from django.contrib import messages
from cart.cart import Cart
from courses.models import Course, Category
from udemy.models import Enroll
from .forms import CourseForm
def add_courses(request):
if request.method == 'POST':
form = CourseForm(request.POST, request.FILES)
if form.is_valid():
title = form.cleaned_data['title']
category = form.cleaned_data['category']
print('------------------------------------------')
print(category)
print('------------------------------------------')
short_descrip = form.cleaned_data['short_description']
descrip = form.cleaned_data['description']
outcome = form.cleaned_data['outcome']
require = form.cleaned_data['requirements']
lang = form.cleaned_data['language']
pr = form.cleaned_data['price']
level = form.cleaned_data['level']
url = form.cleaned_data['video_url']
photo = form.cleaned_data['thumbnail']
course_instance = Course(title=title, user=request.user, category=category, short_description=short_descrip,
description=descrip, outcome=outcome, requirements=require, language=lang, price=pr, level=level, video_url=url, thumbnail=photo)
course_instance.save()
messages.success(
request, f'{course_instance}The course has been added successfully.', 'green')
return redirect('courses:add_courses')
else:
form = CourseForm()
return render(request, 'courses/tecah.html', {'form': form})
Add a block internalStyle
in layouts/base.html
.
layouts/base.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hogwarts</title>
{% block internalStyle %}
{% endblock internalStyle %}
{% include 'partials/header.html' %}
</head>
<body class="gray-bg">
{% include 'partials/navbar.html' %}
{% block content %}{% endblock %}
{% include 'partials/footer.html' %}
{% include 'partials/scripts.html' %}
</body>
</html>
Answered By - Sunderam Dubey
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.