Package: dc-django-base
Included LibrariesThe following libraries are made available to your application bydc-django-base.Python Libraries:django-widget-tweaksdjango-allauthdjango-gravatar2seleniumJavascriptbootstrap 3.3.2jquery 2.1.3jquery cookie 1.4.1jquery form 3.51InstallationSettingsStart the site’s settings by importing thebase_settingsfile:from dcbase.base_settings import *Refer to this file to see the complete list of settings that are included by default. The following are settings that your
sitemustprovide:BASE_DIR (typicallyos.path.dirname(os.path.dirname(__file__)))SECRET_KEY (source the production key from a secure place,nota text file in a public source repository)ROOT_URLCONFWSGI_APPLICATIONDATABASESEMAIL_BACKEND (consider usingdjango.core.mail.backends.console.EmailBackendfor testing)Add the site’s apps toINSTALLED_APPSby prepending them to the base apps:INSTALLED_APPS = (
    'some_app',
    'allauth.socialaccount.providers.google',
) + INSTALLED_APPSOther “list” settings can be modified in a similar way.Because the order of middleware is important it may be required to copy and modify the entireMIDDLEWARE_CLASSESsetting
to inject a new middleware class in the middle of the list.Multiple SettingsA project often needs to maintain multiple settings files. For example, a project may require different settings for it’s
development, staging, and production sites. Follow this pattern to allow easy switching between settings.First, create asettings_common.pyfile. Fill this file with settings that are common to all configurations. Normally,
this file would importdcbase.base_settingsas described above and include settings likeBASE_DIR,ROOT_URLCONF,INSTALLED_APPS, etc. For safety,neverinclude a setting here that could expose the production site to danger, such asSECRET_KEYorDEBUG = True.Create a settings file for each specific configuration. Include the common settings file (e.g.from .settings_common import *)
and add settings that are unique to the specific installation. For example, create asettings_dev.pyfor development settings andsettings_prod.pyfor production settings. This file will normally contain settings likeSECRET_KEY,DATABASES,ALLOWED_HOSTS, etc. Beverycareful how the production settings file is managed and versioned to avoid exposing sensitive
information such as the secret key and database credentials.Finally, create a symlink to the specific settings file. For example,ln-ssettings_prod.py settings.py.UrlsInclude the following urls in the site’s urlconf:url(r'', include('dcbase.urls')),TemplatesCreate abase.htmlin the root of your templates directory. Extenddcbase/base.htmland override
blocks that are global to your site. For example:{% extends "dcbase/base.html" %}

{% block headerBarBrand %}My Site Brand{% endblock %}
{% block footerBar %}
    Footer content!
{% endblock %}TemplatesDC-Base provides templates to override and include.BaseThedcbase/base.htmlprovides the basic page framework and layout. Provide your site’s base template by extending this template
and overriding the following blocks.pageTitle: title of the page, as it will appear in the browser window’s title barstyle: inline CSS to include in the page style tag. you need to include your own enclosing <style> element.head: extra content to include in the page head tag. use this to link external css, add meta tags, etc.headerBarBrand: content for the “brand” link in the upper right, usually the app title or site logoheaderBarBrandLink: target of the “brand” link, usually the app’s home page. default is site root.headerBarLeft: extra nav items (<li>’s) to include on the left side of the header barheaderBarRight: extra nav items (<li>’s) to include on the right side of the header barcontent: the main content of the page. should normally start with a div with class “container” or “container-fluid”footerBar: content for the footer nav barscript: any additional scripts or script links the page needs. inline scripts must supply their own enclosing <script> tagNarrow Dialog BaseExtend fromdcbase/base-narrow-dialog.htmlfor any page that is just a single, vertical form or dialog. Override the following
blocks to provide the dialog content:panelHeading: title of the dialog panel. include any required <h*> tags.panelType: the type of panel (e.g. success, danger, etc.). default is “default”panelBody: content of the dialog panelFormsIncludedcbase/form.htmlordcbase/form-horizontal.htmlto create consistently styled forms. These templates expect a context
variable calledform.Set theautofocuscontext variable to the id of a form field which should be automatically focused when the page loads. For example:{% include "dcbase/form.html" with autofocus="id_important_field" %}Pop-up Ajax FormsCreate an AJAX-ready form inside a pop-up dialog by following this pattern. First create a view using the standard Django form
pattern. When the form is new or contains errors then render a template that contains the form as it would appear inside the
content portion of a boostrap modal dialog. The default templatedcbase/form/popup-form.htmlshould be suitable for most cases.
This template can either be extended or used directly.To extend the template, override the “url” block to supply the form action, override the “title” block to supply a title for the
dialog, and, optionally, override the “footer” block to provide controls such as submit buttons. If the “footer” block is not overridden
then Submit and Cancel buttons will be provided by default.Normally, only the url, title, and submit button text need to be changed. In this case the popup-form.html template can be used directly.
Supply a template render context variable “form_url”, “dialog_title”, and “submit_text” to override these values without extending
the template. If no text is given for the submit button then the default of “Submit” is used.When the form is valid the view can take one of two actions. Either render the template again with a new form (for a “submit
another” pattern) or return a JSON response containing information on how the page should behave.The JSON response must be a map. It must have a key called “action” that describes what action the page should take. Possible
values are:reload: The page will be reloaded at the current URL.close: The modal dialog will be closed and destroyed.redirect: The page will be redirected to the url given by the “url” member of the JSON response.For example, returning a JSON response of{action: 'redirect', url: '/foo'}will cause the page to redirect to /foo.If using class-based views, include the PopupFormMixin in the list of base classesbeforethe other base view classes. This
mixin class allows the following customizations:Class-level Propertiesform_valid_action: The action to take when the form is valid. Must be a PopupValidAction value. Default is reload.form_url: URL that generates and handles this form. Default is to use the path portion of the incoming HTTP request.dialog_title: Text to put in the header bar of the pop-up dialog. Default is None.submit_text: Text for the default submit button. Default is “Submit”.submit_style: Bootstrap style (e.g. info, danger, etc.) for the default submit button. Default is “primary”.success_url: The URL to redirect to when the action is redirect.MethodsEach of the above class-level properties has a corresponding “get_*” method. Additionally, the following methods can be overridden
or extended:popup_form_valid(): Returns an HttpResponse as appropriate for the view’s action.get_new_form(): Returns a new form instance with initial data, regardless of any data on the incoming request.Launch the pop-up form by calling thedcbase.popupAjaxForm(options)function. The “options” argument is an object which accepts
the following values:url: (Required) The URL of the view that renders the form.small: Boolean; true if the modal popup should be narrow. Default false.afterLoad: function to be called after the form content is loaded from the server. The function is passed one argument: the modal-content div.Template Tagsuser_tags{% userNameLink user %}: insert a link to the given user’s profileUser ProfilesCreate app-specific user profile data by following these instructions.Create a database model to encapsulate the profile data. Give it aOneToOneFieldto theUsermodel and call ituser.Create aModelFormto update the new profile model.Create a URL to the view that will edit the new profile model. To be consistent with other profile urls it should be in the form
of^accounts/profile/edit/CATEGORY/$, where CATEGORY is unique to your app.  Make sure the url has a name, such asaccount_profile_edit_CATEGORY.Create the view for the above URL. The view class should look similar to this:@profile_form_view()
class ProfileEditCATEGORYView(ProfileEditFormView):
    form_class = MyProfileForm
    profile_nav_name = _('Nav Name')
    profile_panel_name = _('Panel Name')
    profile_edit_url = reverse_lazy('account_profile_edit_CATEGORY')

profileEditCATEGORYView = login_required(ProfileEditCATEGORYView.as_view())The class-level attribute are:profile_nav_name: the title that will appear on the user profile navigation barprofile_panel_name: the title that will appear on the panel that holds the formprofile_edit_url: URL to the page that allows editing of this profile modelAfter these things are done a new pane will appear in the user’s profile edit page. This new page will contain the form for the
apps profile model.New users will automatically get an instance of the new profile model in the database. If this is a new profile model for a site
with existing users then be sure to use a database migration to create an instance for every existing user.TestingThis project provides several classes with helper methods for testing. These classes are outlined below.Base Test CaseAn abstract base test class is provided asdcbase.tests.BaseTestCase. This class provides the following methods:randStr: generate a random stringcreateUser: create a normal usercreateAdminUser: create an admin usercreateSuperUser: create a super userexpireSession: expire a sessionlogInAs: log a user inlogout: logs out the currently logged in userUnit TestingNormal “unit” tests should derive fromdcbase.tests.unit.UnitTestCase. This class provides the following methods:assertResponseStatusIsOkassertResponseStatusIsNotFoundassertResponseStatusIsNotAuthorizedRequires Login MixinThedcbase.tests.unit.view.mixin.RequiresLoginclass is a mixin class for testing views that verifies that the
view requires a logged in user. This mixin tests that:An anonymous user is redirected to the log in pageThe view returns status ok for logged in usersThis mixin class requires thatself.urlcontains the url of the view under test.Browser TestingBrowser testing, using selenium webdriver, is comprised of two main parts. First, aPageObjectmust be created to
represent each page that the tests will interact with. Second, a test case derived fromdcbase.tests.browser.BrowserTestCasemust be created for the page under test. Each page object and test case has
a property,browser, which is the selenium webdriver object for the browser used in the tests.Page ObjectA page object abstracts all interaction with a web page. Tests should never make selenium calls directly. Follow this pattern
to create a page object:class ThingDetailPage(PageObject):
    _urlPattern = 'thing:detail'
    _pageName = 'Thing Detail'The PageObject requires 2 class-level attributes:_urlPatternand_pageName. The url pattern specifies a named URL pattern
for the page under test. The page name is used for logging purposes.Create a new instance of a page object by passing it a selenium webdriver instance and any other keyword arguments necessary to
fill in the variables fields of the url pattern. For example:page = ThingDetailPage(self.browser, thingId = 123)When a page object is created it will verify that the browser is currently at the correct URL for the page. A runtime error is
raised if the browser is currently at any other URL.BrowserTestCaseThe browser test case derives fromBaseTestCaseand provides several other features. Create a new browser test case using this
pattern:class TestThingDetail(BrowserTestCase):
    _pageClass = ThingDetailPage
    _requiresLogin = True           # Optional

    def setUp(self):
        thing = create_a_thing()
        self._urlFields['thingId'] = thing.id
        super().setUp()In the above example_pageClassis the class of the PageObject for the page under test. The_requiresLoginproperty tells
the test case that this page requires the user to be logged in.  When a browser test case starts it will launch the browser,
log in a user if required, and then browse to the page represented by the given PageObject. Variable fields for the page object
URL can be provided during the test case’s setUp method, as shown above. An instance of the page object is available from a
property calledpage.By default,BrowserTestCaseuses the “Chrome” webdriver. Set theBROWSERenvironment variable to the name of a different
webdriver class to change which browser is used to run the tests.