use crispy with bootstrap4 for forms, job creation view with autocomplete tags
This commit is contained in:
parent
d122a1db39
commit
7d4195fc6c
9 changed files with 111 additions and 5 deletions
|
@ -39,6 +39,18 @@ INSTALLED_APPS = [
|
|||
'django.contrib.staticfiles',
|
||||
]
|
||||
|
||||
# Libraries and other apps
|
||||
INSTALLED_APPS += [
|
||||
'crispy_forms',
|
||||
|
||||
# Used for autocomplete and dynamic creation of tags.
|
||||
# Ff this widget is required for admin, place these
|
||||
# before 'django.contrib.admin' app
|
||||
'dal',
|
||||
'dal_select2',
|
||||
]
|
||||
|
||||
# Our apps
|
||||
INSTALLED_APPS += [
|
||||
'jobs',
|
||||
]
|
||||
|
@ -122,3 +134,6 @@ USE_TZ = True
|
|||
# https://docs.djangoproject.com/en/2.1/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
|
||||
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
||||
|
|
27
jobs/autocomplete.py
Normal file
27
jobs/autocomplete.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
from dal import autocomplete
|
||||
|
||||
from .models import Tag
|
||||
|
||||
|
||||
class AuthenticatedUserCreateMixin():
|
||||
''' By default, autocomplete-light only allows creation of
|
||||
choices if the user has add permission on the model. However,
|
||||
we need to allow any authenticated user to create tags
|
||||
'''
|
||||
def has_add_permission(self, request):
|
||||
print("i am called", request.user)
|
||||
return request.user.is_authenticated
|
||||
|
||||
|
||||
class TagAutocomplete(
|
||||
AuthenticatedUserCreateMixin, autocomplete.Select2QuerySetView):
|
||||
def get_queryset(self):
|
||||
if not self.request.user.is_authenticated:
|
||||
return Tag.objects.none()
|
||||
|
||||
qs = Tag.objects.all()
|
||||
|
||||
if self.q:
|
||||
qs = qs.filter(name__icontains=self.q)
|
||||
|
||||
return qs
|
21
jobs/forms.py
Normal file
21
jobs/forms.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
from django import forms
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Submit
|
||||
from dal.autocomplete import ModelSelect2Multiple
|
||||
|
||||
from .models import Job
|
||||
|
||||
|
||||
class JobForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Job
|
||||
fields = ('title', 'description', 'tags')
|
||||
widgets = {
|
||||
'tags': ModelSelect2Multiple(url='jobs:tag-autocomplete')
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.helper = FormHelper()
|
||||
self.helper.form_method = 'post'
|
||||
self.helper.add_input(Submit('submit', 'Post Job'))
|
|
@ -9,6 +9,9 @@ User = get_user_model()
|
|||
class Tag(models.Model):
|
||||
name = models.CharField(max_length=255, unique=True, db_index=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<a class="p-2 text-dark" href="#">Tags</a>
|
||||
<a class="p-2 text-dark" href="#">Jobs</a>
|
||||
</nav>
|
||||
<a class="btn btn-outline-primary" href="#">Login</a>
|
||||
<a class="btn btn-outline-primary" href="{% url 'jobs:create' %}">Post a job</a>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
|
12
jobs/templates/jobs/job_form.html
Normal file
12
jobs/templates/jobs/job_form.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block title %}Post a Job{% endblock %}
|
||||
|
||||
{% load crispy_forms_tags %}
|
||||
|
||||
{% block body_content %}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{% crispy form %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
14
jobs/urls.py
14
jobs/urls.py
|
@ -1,9 +1,21 @@
|
|||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
from . import autocomplete as autocomplete_views
|
||||
|
||||
app_name = 'jobs'
|
||||
urlpatterns = [
|
||||
path('', views.Index.as_view(), name='index'),
|
||||
path('jobs/', views.JobList.as_view(), name='jobs'),
|
||||
path('jobs/create/', views.JobCreate.as_view(), name='create'),
|
||||
path('jobs/', views.JobList.as_view(), name='list'),
|
||||
]
|
||||
|
||||
|
||||
# autocomplete endpoints
|
||||
urlpatterns += [
|
||||
path(
|
||||
'tag-autocomplete/',
|
||||
autocomplete_views.TagAutocomplete.as_view(create_field='name'),
|
||||
name='tag-autocomplete',
|
||||
),
|
||||
]
|
|
@ -1,7 +1,11 @@
|
|||
from django.shortcuts import render
|
||||
from django.views.generic import TemplateView, ListView
|
||||
from django.urls import reverse_lazy
|
||||
from django.views.generic import (
|
||||
TemplateView, ListView, CreateView
|
||||
)
|
||||
|
||||
from .models import Job
|
||||
from .forms import JobForm
|
||||
|
||||
|
||||
class Index(TemplateView):
|
||||
template_name = 'jobs/index.html'
|
||||
|
@ -11,3 +15,13 @@ class JobList(ListView):
|
|||
context_object_name = 'jobs'
|
||||
model = Job
|
||||
|
||||
|
||||
class JobCreate(CreateView):
|
||||
model = Job
|
||||
form_class = JobForm
|
||||
success_url = reverse_lazy("jobs:list")
|
||||
|
||||
def form_valid(self, form):
|
||||
obj = form.save(commit=False)
|
||||
obj.posted_by = self.request.user
|
||||
return super().form_valid(form)
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
Django==2.1.2
|
||||
Django==2.1.2
|
||||
django-crispy-forms==1.7.2
|
||||
git+https://github.com/yourlabs/django-autocomplete-light.git#egg=django-autocomplete-light
|
||||
|
|
Loading…
Reference in a new issue