base

https://gitlab.com/kb/base

BaseMixin

https://gitlab.com/kb/base/blob/master/base/view_utils.py

The BaseMixin class adds the following to the template context:

  • path: self.request.path or home if the path is /
  • today: todays date (datetime.today())
  • request_path: self.request.path

Bullet (Hide)

If you create a form with a RadioSelect widget e.g:

send_email = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES)

Then you can hide the bullets on the page by using the kb-hide-bullet style e.g:

{% include '_form.html' with form_class='kb-hide-bullet' %}

Date Picker

Using RequiredFieldForm will automatically set date fields to use the zebra datepicker control e.g:

# forms.py
from base.form_utils import RequiredFieldForm

class EventForm(RequiredFieldForm):

Warning

If your date control isn’t working as a date picker, then check your form code to see if you call self.fields[name].widget.attrs.update({'class'... on the field. This will overwrite the update done by the __init__ method on RequiredFieldForm.

File and Image Upload

If you include the _form.html template and you want to upload files, the add the multipart option:

{% include '_form.html' with multipart=True %}

FileDropInput Widget

To display a drag and drop file upload, set the widget for your form to FileDropInput.

For example assuming the following model is defined in your models.py:

class Document(TimedCreateModifyDeleteModel):
    file = models.FileField(upload_to='document')
    description = models.CharField(max_length=256)

    class Meta:
        verbose_name = 'Document'
        verbose_name_plural = 'Documents'

    def __str__(self):
        return '{}: {}'.format(self.file, self.description)

You can define a model form called DocumentForm as follows:

from django import forms
from base.form_utils import FileDropInput
from .models import Document

class DocumentForm(models.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name in ('file', 'description'):
            self.fields[name].widget.attrs.update(
                {'class': 'pure-input-2-3'}
            )

    class Meta:
        model = Document
        fields = (
            'file',
            'description',
        )
        widgets = {'file': FileDropInput}

or using RequiredFieldForm (which sets the widget to FileDropInput for all FileField and ImageFields) as follows:

from base.form_utils import RequiredFieldForm
from .models import Document

class DocumentForm(RequiredFieldForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name in ('file', 'description'):
            self.fields[name].widget.attrs.update(
                {'class': 'pure-input-2-3'}
            )

    class Meta:
        model = Document
        fields = (
            'file',
            'description',
        )

RedirectNextMixin

from base.view_utils import BaseMixin, RedirectNextMixin

Note

This example is for use with an update view and the POST method.

Add the request context processor to settings:

'context_processors': [
    # ...
    'django.template.context_processors.request',

In the calling template:

<a href="{% url 'dash.document.update' document.pk %}?next={{ request.path }}" class="pure-menu-link">

In the view, add the RedirectNextMixin:

from django.contrib.auth import REDIRECT_FIELD_NAME
from base.view_utils import BaseMixin, RedirectNextMixin

class ContactDetailView(
    LoginRequiredMixin, StaffuserRequiredMixin,
    RedirectNextMixin, BaseMixin, DetailView):

If required, add a get_success_url method:

def get_success_url(self):
    next_url = self.request.POST.get(REDIRECT_FIELD_NAME)
    if next_url:
        return next_url
    else:
        return reverse('dash.document.detail', args=[self.object.pk])

Our standard _form.html template includes this section:

  {% if next %}
    <input type="hidden" name="next" value="{{ next }}" />
  {% endif %}
</form>

In the menu of the form template:

<li class="pure-menu-item">
  {% if next %}
    <a href="{{ next }}" class="pure-menu-link">
      <i class="fa fa-reply"></i>
    </a>
  {% else %}
    <a href="{% url 'dash.document.issue.detail' object.pk %}" class="pure-menu-link">
      <i class="fa fa-reply"></i>
      Document
    </a>
  {% endif %}
</li>

RequiredFieldForm

https://gitlab.com/kb/base/blob/master/base/form_utils.py

e.g:

class SnippetForm(RequiredFieldForm):

URL

We have a few standard URLs:

  • logout
  • login
  • project.home the home page of the web site.
  • project.dash the home page for a member of staff (or logged in user if the project requires it).
  • project.settings, the project settings. Usually only accessible to a member of staff.