├── .gitignore ├── README.md ├── apps ├── apps │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ ├── views.py │ └── wsgi.py ├── books_cbv │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── books_cbv │ │ │ ├── book_confirm_delete.html │ │ │ ├── book_form.html │ │ │ └── book_list.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── books_fbv │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── books_fbv │ │ │ ├── book_confirm_delete.html │ │ │ ├── book_form.html │ │ │ └── book_list.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── books_fbv_user │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── books_fbv_user │ │ │ ├── book_confirm_delete.html │ │ │ ├── book_form.html │ │ │ └── book_list.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── manage.py └── theme │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ └── __init__.py │ ├── models.py │ ├── static │ └── css │ │ └── style.css │ ├── templates │ ├── base.html │ ├── home.html │ └── registration │ │ └── login.html │ ├── tests.py │ └── views.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | db.sqlite3 2 | __pycache__ 3 | *.swp 4 | /venv 5 | /.vscode 6 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Django CRUD Example Apps 2 | 3 | This is a small Django project to demonstrate Django CRUD functionality, it 4 | consist of 3 small applications: 5 | 6 | - books\_cbv: Implement CRUD using CBV (Class Based Views). 7 | - books\_fbv: Implement CRUD using FBV (Function Based Views). 8 | - books\_fbv\_user: add user interaction to books\_fbv example. 9 | 10 | 11 | ## Install Required Packages 12 | 13 | The Django CRUD project only need a single Python package "Django", it was built and 14 | tested with Django 2.x version. To install it use the following command: 15 | 16 | pip install -r requirements.txt 17 | 18 | Django 2 requires Python 3, if you need help setting up Python 3 on your machine you can consult 19 | DigitalOcean great documentation on 20 | [How To Install and Set Up a Local Programming Environment for Python 3](https://www.digitalocean.com/community/tutorial_series/how-to-install-and-set-up-a-local-programming-environment-for-python-3) 21 | 22 | ## Running the Application 23 | 24 | Before running the application we need to create the needed DB tables: 25 | 26 | ./manage.py migrate 27 | 28 | Now you can run the development web server: 29 | 30 | ./manage.py runserver 31 | 32 | To access the applications go to the URL 33 | 34 | 35 | ## I need a user and password to access "books\_fbv\_user" 36 | 37 | Yes, the "books\_fbv\_user" demonstrate how CRUD can work with Django users, and you do 38 | need to create a user to test it, you can create a user using the following command: 39 | 40 | ./manage.py createsuperuser 41 | 42 | To create a normal user (non super user), you must login to the admin page and 43 | create it: 44 | -------------------------------------------------------------------------------- /apps/apps/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rayed/django_crud/14b311ab166f03cf9e8d91086ec6973ab05f9f15/apps/apps/__init__.py -------------------------------------------------------------------------------- /apps/apps/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for zzz project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.0.5. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.0/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.0/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = '0ux_%=7!81&z=^uj5iw@tue#7zkfn9lk)=*d147(g+$5t$l9nz' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 41 | 'theme', 42 | 'books_cbv', 43 | 'books_fbv', 44 | 'books_fbv_user', 45 | ] 46 | 47 | MIDDLEWARE = [ 48 | 'django.middleware.security.SecurityMiddleware', 49 | 'django.contrib.sessions.middleware.SessionMiddleware', 50 | 'django.middleware.common.CommonMiddleware', 51 | 'django.middleware.csrf.CsrfViewMiddleware', 52 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 53 | 'django.contrib.messages.middleware.MessageMiddleware', 54 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 55 | ] 56 | 57 | ROOT_URLCONF = 'apps.urls' 58 | 59 | TEMPLATES = [ 60 | { 61 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 62 | 'DIRS': [], 63 | 'APP_DIRS': True, 64 | 'OPTIONS': { 65 | 'context_processors': [ 66 | 'django.template.context_processors.debug', 67 | 'django.template.context_processors.request', 68 | 'django.contrib.auth.context_processors.auth', 69 | 'django.contrib.messages.context_processors.messages', 70 | ], 71 | }, 72 | }, 73 | ] 74 | 75 | WSGI_APPLICATION = 'apps.wsgi.application' 76 | 77 | 78 | # Database 79 | # https://docs.djangoproject.com/en/2.0/ref/settings/#databases 80 | 81 | DATABASES = { 82 | 'default': { 83 | 'ENGINE': 'django.db.backends.sqlite3', 84 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 85 | } 86 | } 87 | 88 | 89 | # Password validation 90 | # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators 91 | 92 | AUTH_PASSWORD_VALIDATORS = [ 93 | { 94 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 95 | }, 96 | { 97 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 98 | }, 99 | { 100 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 101 | }, 102 | { 103 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 104 | }, 105 | ] 106 | 107 | 108 | # Internationalization 109 | # https://docs.djangoproject.com/en/2.0/topics/i18n/ 110 | 111 | LANGUAGE_CODE = 'en-us' 112 | 113 | TIME_ZONE = 'UTC' 114 | 115 | USE_I18N = True 116 | 117 | USE_L10N = True 118 | 119 | USE_TZ = True 120 | 121 | 122 | # Static files (CSS, JavaScript, Images) 123 | # https://docs.djangoproject.com/en/2.0/howto/static-files/ 124 | 125 | STATIC_URL = '/static/' 126 | STATICFILES_DIRS = [ 127 | os.path.join(BASE_DIR, 'static'), 128 | ] 129 | #LOGIN_URL = '/accounts/login/' 130 | 131 | LOGIN_REDIRECT_URL = '/books_fbv_user/' 132 | LOGOUT_REDIRECT_URL = '/' 133 | 134 | 135 | DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' -------------------------------------------------------------------------------- /apps/apps/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import include, path 2 | from django.contrib import admin 3 | 4 | import theme.views 5 | 6 | urlpatterns = [ 7 | path('', theme.views.home), 8 | path('books_cbv/', include('books_cbv.urls')), 9 | path('books_fbv/', include('books_fbv.urls')), 10 | path('books_fbv_user/', include('books_fbv_user.urls')), 11 | 12 | # Enable built-in authentication views 13 | path('accounts/', include('django.contrib.auth.urls')), 14 | # Enable built-in admin interface 15 | path('admin/', admin.site.urls), 16 | ] 17 | -------------------------------------------------------------------------------- /apps/apps/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render -------------------------------------------------------------------------------- /apps/apps/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for apps project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "apps.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /apps/books_cbv/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rayed/django_crud/14b311ab166f03cf9e8d91086ec6973ab05f9f15/apps/books_cbv/__init__.py -------------------------------------------------------------------------------- /apps/books_cbv/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from books_cbv.models import Book 3 | 4 | admin.site.register(Book) -------------------------------------------------------------------------------- /apps/books_cbv/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BooksCbvConfig(AppConfig): 5 | name = 'books_cbv' 6 | -------------------------------------------------------------------------------- /apps/books_cbv/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.5 on 2018-05-11 15:11 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.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('name', models.CharField(max_length=200)), 19 | ('pages', models.IntegerField()), 20 | ], 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /apps/books_cbv/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rayed/django_crud/14b311ab166f03cf9e8d91086ec6973ab05f9f15/apps/books_cbv/migrations/__init__.py -------------------------------------------------------------------------------- /apps/books_cbv/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.urls import reverse 3 | 4 | 5 | class Book(models.Model): 6 | name = models.CharField(max_length=200) 7 | pages = models.IntegerField() 8 | 9 | def __str__(self): 10 | return self.name 11 | 12 | def get_absolute_url(self): 13 | return reverse('books_cbv:book_edit', kwargs={'pk': self.pk}) -------------------------------------------------------------------------------- /apps/books_cbv/templates/books_cbv/book_confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Books CBV: Delete?

6 | 7 |
{% csrf_token %} 8 | Are you sure you want to delete "{{ object }}" ?
9 | 10 |
11 | 12 | {% endblock %} -------------------------------------------------------------------------------- /apps/books_cbv/templates/books_cbv/book_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Books CBV: Edit

6 | 7 |
{% csrf_token %} 8 | {{ form.as_p }} 9 | 10 |
11 | 12 | {% endblock %} -------------------------------------------------------------------------------- /apps/books_cbv/templates/books_cbv/book_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Books CBV

6 | 7 | 15 | 16 | New 17 | 18 | {% endblock %} -------------------------------------------------------------------------------- /apps/books_cbv/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /apps/books_cbv/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from . import views 4 | 5 | app_name = 'books_cbv' 6 | 7 | urlpatterns = [ 8 | path('', views.BookList.as_view(), name='book_list'), 9 | path('new/', views.BookCreate.as_view(), name='book_new'), 10 | path('edit//', views.BookUpdate.as_view(), name='book_edit'), 11 | path('delete//', views.BookDelete.as_view(), name='book_delete'), 12 | ] -------------------------------------------------------------------------------- /apps/books_cbv/views.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponse 2 | from django.views.generic import TemplateView,ListView 3 | from django.views.generic.edit import CreateView, UpdateView, DeleteView 4 | from django.urls import reverse_lazy 5 | 6 | from .models import Book 7 | 8 | class BookList(ListView): 9 | model = Book 10 | 11 | class BookCreate(CreateView): 12 | model = Book 13 | fields = ['name', 'pages'] 14 | success_url = reverse_lazy('books_cbv:book_list') 15 | 16 | class BookUpdate(UpdateView): 17 | model = Book 18 | fields = ['name', 'pages'] 19 | success_url = reverse_lazy('books_cbv:book_list') 20 | 21 | class BookDelete(DeleteView): 22 | model = Book 23 | success_url = reverse_lazy('books_cbv:book_list') -------------------------------------------------------------------------------- /apps/books_fbv/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rayed/django_crud/14b311ab166f03cf9e8d91086ec6973ab05f9f15/apps/books_fbv/__init__.py -------------------------------------------------------------------------------- /apps/books_fbv/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from books_fbv.models import Book 3 | 4 | admin.site.register(Book) -------------------------------------------------------------------------------- /apps/books_fbv/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BooksFbvConfig(AppConfig): 5 | name = 'books_fbv' 6 | -------------------------------------------------------------------------------- /apps/books_fbv/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.5 on 2018-05-11 15:11 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.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('name', models.CharField(max_length=200)), 19 | ('pages', models.IntegerField()), 20 | ], 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /apps/books_fbv/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rayed/django_crud/14b311ab166f03cf9e8d91086ec6973ab05f9f15/apps/books_fbv/migrations/__init__.py -------------------------------------------------------------------------------- /apps/books_fbv/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.urls import reverse 3 | 4 | 5 | class Book(models.Model): 6 | name = models.CharField(max_length=200) 7 | pages = models.IntegerField() 8 | 9 | def __str__(self): 10 | return self.name 11 | 12 | def get_absolute_url(self): 13 | return reverse('books_fbv:book_edit', kwargs={'pk': self.pk}) -------------------------------------------------------------------------------- /apps/books_fbv/templates/books_fbv/book_confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Books FBV: Delete?

6 | 7 |
{% csrf_token %} 8 | Are you sure you want to delete "{{ object }}" ?
9 | 10 |
11 | 12 | {% endblock %} -------------------------------------------------------------------------------- /apps/books_fbv/templates/books_fbv/book_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Books FBV: Edit

6 | 7 |
{% csrf_token %} 8 | {{ form.as_p }} 9 | 10 |
11 | 12 | {% endblock %} -------------------------------------------------------------------------------- /apps/books_fbv/templates/books_fbv/book_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Books FBV

6 | 7 |
    8 | {% for book in object_list %} 9 |
  • {{ book.name }} ({{ book.pages }} Pages) 10 | edit 11 | delete 12 |
  • 13 | {% endfor %} 14 |
15 | 16 | New 17 | 18 | {% endblock %} -------------------------------------------------------------------------------- /apps/books_fbv/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /apps/books_fbv/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from books_fbv import views 4 | 5 | app_name = 'books_fbv' 6 | 7 | urlpatterns = [ 8 | path('', views.book_list, name='book_list'), 9 | path('new/', views.book_create, name='book_new'), 10 | path('edit//', views.book_update, name='book_edit'), 11 | path('delete//', views.book_delete, name='book_delete'), 12 | ] -------------------------------------------------------------------------------- /apps/books_fbv/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, redirect, get_object_or_404 2 | from django.forms import ModelForm 3 | 4 | from .models import Book 5 | 6 | class BookForm(ModelForm): 7 | class Meta: 8 | model = Book 9 | fields = ['name', 'pages'] 10 | 11 | def book_list(request, template_name='books_fbv/book_list.html'): 12 | book = Book.objects.all() 13 | data = {} 14 | data['object_list'] = book 15 | return render(request, template_name, data) 16 | 17 | def book_create(request, template_name='books_fbv/book_form.html'): 18 | form = BookForm(request.POST or None) 19 | if form.is_valid(): 20 | form.save() 21 | return redirect('books_fbv:book_list') 22 | return render(request, template_name, {'form':form}) 23 | 24 | def book_update(request, pk, template_name='books_fbv/book_form.html'): 25 | book= get_object_or_404(Book, pk=pk) 26 | form = BookForm(request.POST or None, instance=book) 27 | if form.is_valid(): 28 | form.save() 29 | return redirect('books_fbv:book_list') 30 | return render(request, template_name, {'form':form}) 31 | 32 | def book_delete(request, pk, template_name='books_fbv/book_confirm_delete.html'): 33 | book= get_object_or_404(Book, pk=pk) 34 | if request.method=='POST': 35 | book.delete() 36 | return redirect('books_fbv:book_list') 37 | return render(request, template_name, {'object':book}) 38 | -------------------------------------------------------------------------------- /apps/books_fbv_user/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rayed/django_crud/14b311ab166f03cf9e8d91086ec6973ab05f9f15/apps/books_fbv_user/__init__.py -------------------------------------------------------------------------------- /apps/books_fbv_user/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from books_fbv_user.models import Book 3 | 4 | admin.site.register(Book) -------------------------------------------------------------------------------- /apps/books_fbv_user/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BooksFbvUserConfig(AppConfig): 5 | name = 'books_fbv_user' 6 | -------------------------------------------------------------------------------- /apps/books_fbv_user/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.5 on 2018-05-11 15:11 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 14 | ] 15 | 16 | operations = [ 17 | migrations.CreateModel( 18 | name='Book', 19 | fields=[ 20 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 21 | ('name', models.CharField(max_length=200)), 22 | ('pages', models.IntegerField()), 23 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 24 | ], 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /apps/books_fbv_user/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rayed/django_crud/14b311ab166f03cf9e8d91086ec6973ab05f9f15/apps/books_fbv_user/migrations/__init__.py -------------------------------------------------------------------------------- /apps/books_fbv_user/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.urls import reverse 3 | from django.conf import settings 4 | 5 | class Book(models.Model): 6 | user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) 7 | name = models.CharField(max_length=200) 8 | pages = models.IntegerField() 9 | 10 | def __str__(self): 11 | return self.name 12 | 13 | def get_absolute_url(self): 14 | return reverse('books_fbv_user:book_edit', kwargs={'pk': self.pk}) -------------------------------------------------------------------------------- /apps/books_fbv_user/templates/books_fbv_user/book_confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Books FBV User: Delete?

6 | 7 |
{% csrf_token %} 8 | Are you sure you want to delete "{{ object }}" ?
9 | 10 |
11 | 12 | {% endblock %} -------------------------------------------------------------------------------- /apps/books_fbv_user/templates/books_fbv_user/book_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Books FBV User: Edit

6 | 7 |
{% csrf_token %} 8 | {{ form.as_p }} 9 | 10 |
11 | 12 | {% endblock %} -------------------------------------------------------------------------------- /apps/books_fbv_user/templates/books_fbv_user/book_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Books FBV User

6 | 7 |
    8 | {% for book in object_list %} 9 |
  • {{ book.name }} ({{ book.pages }} Pages) 10 | edit 11 | delete 12 |
  • 13 | {% endfor %} 14 |
15 | 16 | New 17 | 18 | {% endblock %} -------------------------------------------------------------------------------- /apps/books_fbv_user/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /apps/books_fbv_user/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from . import views 4 | 5 | app_name = 'books_fbv_user' 6 | 7 | urlpatterns = [ 8 | path('', views.book_list, name='book_list'), 9 | path('new/', views.book_create, name='book_new'), 10 | path('edit//', views.book_update, name='book_edit'), 11 | path('delete//', views.book_delete, name='book_delete'), 12 | ] -------------------------------------------------------------------------------- /apps/books_fbv_user/views.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.decorators import login_required 2 | from django.shortcuts import render, redirect, get_object_or_404 3 | from django.forms import ModelForm 4 | 5 | from .models import Book 6 | 7 | class BookForm(ModelForm): 8 | class Meta: 9 | model = Book 10 | fields = ['name', 'pages'] 11 | 12 | @login_required 13 | def book_list(request, template_name='books_fbv_user/book_list.html'): 14 | if request.user.is_superuser: 15 | book = Book.objects.all() 16 | else: 17 | book = Book.objects.filter(user=request.user) 18 | data = {} 19 | data['object_list'] = book 20 | return render(request, template_name, data) 21 | 22 | @login_required 23 | def book_create(request, template_name='books_fbv_user/book_form.html'): 24 | form = BookForm(request.POST or None) 25 | if form.is_valid(): 26 | book = form.save(commit=False) 27 | book.user = request.user 28 | book.save() 29 | return redirect('books_fbv_user:book_list') 30 | return render(request, template_name, {'form':form}) 31 | 32 | @login_required 33 | def book_update(request, pk, template_name='books_fbv_user/book_form.html'): 34 | if request.user.is_superuser: 35 | book= get_object_or_404(Book, pk=pk) 36 | else: 37 | book= get_object_or_404(Book, pk=pk, user=request.user) 38 | form = BookForm(request.POST or None, instance=book) 39 | if form.is_valid(): 40 | form.save() 41 | return redirect('books_fbv_user:book_list') 42 | return render(request, template_name, {'form':form}) 43 | 44 | @login_required 45 | def book_delete(request, pk, template_name='books_fbv_user/book_confirm_delete.html'): 46 | if request.user.is_superuser: 47 | book= get_object_or_404(Book, pk=pk) 48 | else: 49 | book= get_object_or_404(Book, pk=pk, user=request.user) 50 | if request.method=='POST': 51 | book.delete() 52 | return redirect('books_fbv_user:book_list') 53 | return render(request, template_name, {'object':book}) 54 | -------------------------------------------------------------------------------- /apps/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "apps.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /apps/theme/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rayed/django_crud/14b311ab166f03cf9e8d91086ec6973ab05f9f15/apps/theme/__init__.py -------------------------------------------------------------------------------- /apps/theme/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /apps/theme/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ThemeConfig(AppConfig): 5 | name = 'theme' 6 | -------------------------------------------------------------------------------- /apps/theme/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rayed/django_crud/14b311ab166f03cf9e8d91086ec6973ab05f9f15/apps/theme/migrations/__init__.py -------------------------------------------------------------------------------- /apps/theme/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /apps/theme/static/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Arial, Helvetica, sans-serif; 3 | width:800px; 4 | margin:auto; 5 | } 6 | 7 | a { 8 | color:#0000EE; 9 | text-decoration:none; 10 | } 11 | 12 | a:hover { 13 | text-decoration:underline; 14 | } 15 | 16 | #user {float:right; } -------------------------------------------------------------------------------- /apps/theme/templates/base.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 17 |
18 | {% block content %} 19 | {% endblock %} 20 |
21 | 23 | 24 | -------------------------------------------------------------------------------- /apps/theme/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 | Class Based Views
6 | Function Based Views
7 | Function Based Views with User Access
8 | 9 | {% endblock %} -------------------------------------------------------------------------------- /apps/theme/templates/registration/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 | {% if form.errors %} 6 |

Your username and password didn't match. Please try again.

7 | {% endif %} 8 | 9 | {% if next %} 10 | {% if user.is_authenticated %} 11 |

Your account doesn't have access to this page. To proceed, 12 | please login with an account that has access.

13 | {% else %} 14 |

Please login to see this page.

15 | {% endif %} 16 | {% endif %} 17 | 18 |
19 | {% csrf_token %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
{{ form.username.label_tag }}{{ form.username }}
{{ form.password.label_tag }}{{ form.password }}
30 | 31 | 32 | 33 |
34 | 35 | {# Assumes you setup the password_reset view in your URLconf #} 36 |

Lost password?

37 | 38 | {% endblock %} -------------------------------------------------------------------------------- /apps/theme/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /apps/theme/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | def home(request): 4 | return render(request, "home.html") -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Django>=3.2.7,<4.0 --------------------------------------------------------------------------------