Skip to content

Commit 5594e7a

Browse files
committed
add crud app django tutorial
1 parent 11c0be5 commit 5594e7a

File tree

88 files changed

+643
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+643
-0
lines changed

README.md

+1

web-programming/bookshop-crud-app-django/books/__init__.py

Whitespace-only changes.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.contrib import admin
2+
# from the models.py file import Book
3+
from .models import Book
4+
5+
# registering the Book to the admin site
6+
admin.site.register(Book)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.apps import AppConfig
2+
3+
4+
class BooksConfig(AppConfig):
5+
default_auto_field = 'django.db.models.BigAutoField'
6+
name = 'books'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from .models import Book
2+
from django.forms import ModelForm
3+
from django import forms
4+
5+
# declaring the ModelForm
6+
class EditBookForm(ModelForm):
7+
8+
class Meta:
9+
# the Model from which the form will inherit from
10+
model = Book
11+
# the fields we want from the Model
12+
fields = '__all__'
13+
# styling the form with bootstrap classes
14+
widgets = {
15+
'title': forms.TextInput(attrs={'class': 'form-control'}),
16+
'author': forms.TextInput(attrs={'class': 'form-control'}),
17+
'price': forms.TextInput(attrs={'class': 'form-control'}),
18+
'isbn': forms.TextInput(attrs={'class': 'form-control'}),
19+
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Generated by Django 4.0.6 on 2022-07-17 08:18
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
initial = True
9+
10+
dependencies = [
11+
]
12+
13+
operations = [
14+
migrations.CreateModel(
15+
name='Book',
16+
fields=[
17+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18+
('title', models.CharField(max_length=100)),
19+
('author', models.CharField(max_length=100)),
20+
('price', models.DecimalField(decimal_places=2, max_digits=10)),
21+
('isbn', models.CharField(max_length=100)),
22+
('image', models.ImageField(upload_to='')),
23+
('created_at', models.DateTimeField(auto_now_add=True, null=True)),
24+
],
25+
options={
26+
'ordering': ['-created_at'],
27+
},
28+
),
29+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 4.0.6 on 2022-07-17 08:29
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('books', '0001_initial'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='book',
15+
name='image',
16+
field=models.ImageField(default='images/', upload_to='images'),
17+
),
18+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 4.0.6 on 2022-07-17 08:29
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('books', '0002_alter_book_image'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='book',
15+
name='image',
16+
field=models.ImageField(default='images/default.jpg', upload_to='images'),
17+
),
18+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 4.0.6 on 2022-07-17 08:34
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('books', '0003_alter_book_image'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='book',
15+
name='image',
16+
field=models.ImageField(default='images/default.jpg', upload_to='images/'),
17+
),
18+
]

web-programming/bookshop-crud-app-django/books/migrations/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from django.db import models
2+
3+
4+
# the Book model with its fields
5+
class Book(models.Model):
6+
title = models.CharField(max_length=100)
7+
author = models.CharField(max_length=100)
8+
price = models.DecimalField(max_digits=10, decimal_places=2)
9+
isbn = models.CharField(max_length=100)
10+
# this is the image for a book, the image will be uploaded to images folder
11+
image = models.ImageField(null=False, blank=False, upload_to='images/')
12+
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
13+
14+
# this is the string represantation, what to display after querying a book/books
15+
def __str__(self):
16+
return f'{self.title}'
17+
18+
# this will order the books by date created
19+
class Meta:
20+
ordering = ['-created_at']
21+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{% extends 'books/base.html' %}
2+
3+
4+
{% block content %}
5+
<div class="row justify-content-center">
6+
<div class="col-md-4">
7+
<a href="{% url 'home' %}" class="my-3 btn btn-dark btn-sm">Go Back</a>
8+
9+
<div class="card shadow-lg">
10+
11+
<div class="card-body">
12+
<!-- the form for adding a book -->
13+
<form method="POST" enctype="multipart/form-data" action="">
14+
15+
<!-- this is for securing the form from malicious attacks -->
16+
{% csrf_token %}
17+
18+
<!-- this is the label and input for the Title -->
19+
<div class="mb-3">
20+
<label class="form-label font-weight-bold">Book Title</label>
21+
<input required type="text" name="title" class="form-control" placeholder="Enter Book Title">
22+
</div>
23+
24+
<!-- this is the label and input for the Author -->
25+
<div class="mb-3">
26+
<label class="form-label font-weight-bold">Author</label>
27+
<input required type="text" name="author" class="form-control" placeholder="Book Author">
28+
</div>
29+
30+
31+
<!-- this is the label and input for the Price -->
32+
<div class="mb-3">
33+
<label class="form-label font-weight-bold">Price</label>
34+
<input required type="number" name="price" class="form-control" placeholder="Price">
35+
</div>
36+
37+
<!-- this is the label and input for the ISBN -->
38+
<div class="mb-3">
39+
<label class="form-label font-weight-bold">ISBN</label>
40+
<input required type="text" name="isbn" class="form-control" placeholder="ISBN">
41+
</div>
42+
43+
<!-- this is the label and input for the Image -->
44+
<div class="mb-3">
45+
<label class="form-label font-weight-bold">Upload Image:</label>
46+
<input required type="file" name="image-file" class="form-control" id="customFile" />
47+
</div>
48+
49+
<!-- Submit button -->
50+
<button type="submit" class="btn btn-success btn-block mb-4">Submit</button>
51+
</form>
52+
</div>
53+
54+
</div>
55+
</div>
56+
</div>
57+
{% endblock %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<title>Book Store</title>
8+
<!-- CSS only -->
9+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
10+
</head>
11+
<body>
12+
{% block content %}
13+
14+
{% endblock %}
15+
</body>
16+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{% extends 'books/base.html' %}
2+
<!-- loads images -->
3+
{% load static %}
4+
5+
6+
{% block content %}
7+
<div class="row justify-content-center">
8+
<div class="col-md-4">
9+
<div class="">
10+
<a href="{% url 'home' %}" class="my-3 btn btn-dark btn-sm">Go Back</a>
11+
</div>
12+
13+
14+
<div style="height: 90vh">
15+
<img class="img-fluid text-center" style="max-width: 100%; max-height: 100%" src="{{ book.image.url }}" alt="">
16+
17+
<h5 class="text-muted">Author: {{ book.author }}</h5>
18+
<small>ISBN: {{ book.isbn }}</small><br>
19+
<small>Price: {{ book.price }}</small><br>
20+
<a href="{% url 'edit-book' book.id %}" class="btn btn-success btn-sm">Edit Book</a>
21+
<a href="{% url 'delete-book' book.id %}" class="btn btn-danger btn-sm">Delete Book</a>
22+
</div>
23+
</div>
24+
</div>
25+
{% endblock %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{% extends 'books/base.html' %}
2+
3+
4+
{% block content %}
5+
<div class="row justify-content-center">
6+
<div class="col-md-4">
7+
<a href="{% url 'home' %}" class="my-3 btn btn-dark btn-sm">Go Back</a>
8+
9+
<div class="card shadow-lg">
10+
11+
<div class="card-body">
12+
<!-- the form for deleting a book -->
13+
<form method="POST" action="">
14+
15+
<!-- this is for securing the form from malicious attacks -->
16+
{% csrf_token %}
17+
18+
<p>Are you sure you want to delete the book '<b>{{ book.title | upper}}</b>'?</p>
19+
20+
<!-- Submit button -->
21+
<button type="submit" class="btn btn-danger btn-block mb-4">Confirm</button>
22+
</form>
23+
</div>
24+
25+
</div>
26+
</div>
27+
</div>
28+
{% endblock %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<!-- inheriting from the base file -->
2+
{% extends 'books/base.html' %}
3+
4+
<!-- this will help render the images -->
5+
{% load static %}
6+
7+
{% block content %}
8+
<div class="container mb-4">
9+
<div class="row">
10+
<!-- side navbar here -->
11+
<div class="col-md-3 mt-3">
12+
<div class="card">
13+
<h4 class="card-header px-3">Menu</h4>
14+
15+
<ul class="list-group list-group-light list-group-small">
16+
<li class="list-group-item px-3"><a href="">Home</a></li>
17+
</ul>
18+
19+
<a href="{% url 'add-book' %}" class="m-2 btn btn-dark btn-sm">Add Book</a>
20+
21+
</div>
22+
</div>
23+
24+
<!-- books here -->
25+
<div class="col-md-9 mt-3">
26+
<div class="row">
27+
<!-- using a for loop to loop through all the books -->
28+
{% for book in books %}
29+
<div class="col-md-4">
30+
<div class="card my-2">
31+
<a href="">
32+
<!-- this is the book image -->
33+
<img src="{{ book.image.url }}" class="card-img-top" style="height:275px" />
34+
</a>
35+
<div class="card-body">
36+
<!-- this is the book title -->
37+
<h4 class="card-text">{{ book.title }}</h4>
38+
</div>
39+
<a href="{% url 'book-detail' book.id %}" class="m-2 btn btn-outline-dark btn-sm">View Book</a>
40+
</div>
41+
</div>
42+
{% endfor %}
43+
44+
</div>
45+
46+
</div>
47+
48+
</div>
49+
</div>
50+
{% endblock %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{% extends 'books/base.html' %}
2+
3+
4+
{% block content %}
5+
<div class="row justify-content-center">
6+
<div class="col-md-4">
7+
<a href="{% url 'home' %}" class="my-3 btn btn-dark btn-sm">Go Back</a>
8+
9+
<div class="card shadow-lg">
10+
11+
<div class="card-body">
12+
<!-- the form for adding a book -->
13+
<form method="POST" enctype="multipart/form-data" action="">
14+
15+
<!-- this is for securing the form from malicious attacks -->
16+
{% csrf_token %}
17+
18+
<p>{{ form }}</p>
19+
20+
<!-- Submit button -->
21+
<button type="submit" class="btn btn-success btn-block mb-4">Update Book</button>
22+
</form>
23+
</div>
24+
25+
</div>
26+
</div>
27+
</div>
28+
{% endblock %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.test import TestCase
2+
3+
# Create your tests here.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from django.urls import path
2+
# this imports all the views from the views.py
3+
from . import views
4+
5+
6+
urlpatterns = [
7+
# this is the home url
8+
path('', views.home, name='home'),
9+
# this is the single book url
10+
path('book-detail/<str:id>/', views.book_detail, name='book-detail'),
11+
# this is the add book url
12+
path('add-book/', views.add_book, name='add-book'),
13+
# this is the edit book url
14+
path('edit-book/<str:id>/', views.edit_book, name='edit-book'),
15+
# this is the delete book url
16+
path('delete-book/<str:id>/', views.delete_book, name='delete-book'),
17+
]

0 commit comments

Comments
 (0)