Django Visualizer
Subpackages
- Graph Loading & Creation
- Colors
- Graph
- GraphCreator
- GraphSummary
- RCV Result
- Read RCVRC JSON
FixIgnoreResidualSurplus
FixNoTransfersTask
FixRankitCombinedTallyResults
FixRankitMissingTransfers
FixRankitMissingWinners
FixRankitNoElimOnLastRound
FixUndeclaredUWITask
HideDecimalsTask
JSONMigrateTask
JSONReader
MakeExhaustedAndSurplusACandidate
MakeTalliesANumber
MigrationError
NormalizeSpecialNames
Admin
Admin page configuration
- class visualizer.admin.HomepageFeaturedElectionAdmin(model, admin_site)
Bases:
ModelAdmin
Administer homepage featured links
- list_display = ('title', 'order', 'column', 'jsonConfig')
- property media
- raw_id_fields = ('jsonConfig',)
- class visualizer.admin.HomepageFeaturedElectionColumnAdmin(model, admin_site)
Bases:
ModelAdmin
Administer homepage featured link columns
- list_display = ('title', 'order')
- property media
- class visualizer.admin.JsonAdmin(model, admin_site)
Bases:
CursorPaginatorAdmin
The admin page to modify JsonConfig
- actions = [<function make_movie>]
- list_display = ('slug', 'title', 'owner', 'numRounds', 'numCandidates', 'uploadedAt', 'movieGenerationStatus')
- property media
- readonly_fields = ('slug', 'title', 'numRounds', 'numCandidates', 'uploadedAt', 'movieGenerationStatus')
- search_fields = ['slug']
- show_full_result_count = False
- view_on_site = True
- visualizer.admin.make_movie(_, request, queryset)
An action from the admin menu that creates a movie
Common
A set of common utilities to be used across modules
- visualizer.common.candidate_renames()
A dictionary mapping how we should rename candidate names
- visualizer.common.get_host(request)
Returns the HTTP_HOST, split for easy mocking
- visualizer.common.intify(notint)
Turn into int if it’s a round number
- visualizer.common.make_complete_url(request, urlWithoutDomain)
Returns the complete URL, including domain
- visualizer.common.percentify(numerator, denominator)
Turn a float into a percentage string. Or, if the denominator is zero, returns an empty string
Forms
Forms enable users to create Models
- class visualizer.forms.UploadByDataTableForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None, renderer=None)
Bases:
UploadForm
Used by the upload form using the DataTables entry
- class Meta
Bases:
Meta
Metadata is all we need here
- fields = ['candidateSidecarFile', 'rotateNames', 'showRoundNumbersOnSankey', 'onlyShowWinnersTabular', 'doUseDescriptionInsteadOfTimeline', 'isPreferentialBlock', 'hideSankey', 'hideTabular', 'doDimPrevRoundColors', 'excludeFinalWinnerAndEliminatedCandidate', 'hideDecimals', 'colorTheme', 'eliminationBarColor', 'dataSourceURL', 'areResultsCertified', 'textForWinner']
- base_fields = {'areResultsCertified': <django.forms.fields.BooleanField object>, 'candidateSidecarFile': <django.forms.fields.FileField object>, 'colorTheme': <django.forms.fields.IntegerField object>, 'dataSourceURL': <django.forms.fields.URLField object>, 'doDimPrevRoundColors': <django.forms.fields.BooleanField object>, 'doUseDescriptionInsteadOfTimeline': <django.forms.fields.BooleanField object>, 'eliminationBarColor': <django.forms.fields.IntegerField object>, 'excludeFinalWinnerAndEliminatedCandidate': <django.forms.fields.BooleanField object>, 'hideDecimals': <django.forms.fields.BooleanField object>, 'hideSankey': <django.forms.fields.BooleanField object>, 'hideTabular': <django.forms.fields.BooleanField object>, 'isPreferentialBlock': <django.forms.fields.BooleanField object>, 'jsonFile': <django.forms.fields.FileField object>, 'onlyShowWinnersTabular': <django.forms.fields.BooleanField object>, 'rotateNames': <django.forms.fields.BooleanField object>, 'showRoundNumbersOnSankey': <django.forms.fields.BooleanField object>, 'textForWinner': <django.forms.fields.IntegerField object>}
- clean_jsonFile()
Converts the datatables json to URCVT json
- declared_fields = {'colorTheme': <django.forms.fields.IntegerField object>, 'eliminationBarColor': <django.forms.fields.IntegerField object>, 'jsonFile': <django.forms.fields.FileField object>, 'textForWinner': <django.forms.fields.IntegerField object>}
- property media
Return all media required to render the widgets on this form.
- class visualizer.forms.UploadForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None, renderer=None)
Bases:
ModelForm
Used by the upload form
- class Meta
Bases:
object
Metadata is all we need here
- fields = ['jsonFile', 'candidateSidecarFile', 'rotateNames', 'showRoundNumbersOnSankey', 'onlyShowWinnersTabular', 'doUseDescriptionInsteadOfTimeline', 'isPreferentialBlock', 'hideSankey', 'hideTabular', 'doDimPrevRoundColors', 'excludeFinalWinnerAndEliminatedCandidate', 'hideDecimals', 'colorTheme', 'eliminationBarColor', 'dataSourceURL', 'areResultsCertified', 'textForWinner']
- model
alias of
JsonConfig
- base_fields = {'areResultsCertified': <django.forms.fields.BooleanField object>, 'candidateSidecarFile': <django.forms.fields.FileField object>, 'colorTheme': <django.forms.fields.IntegerField object>, 'dataSourceURL': <django.forms.fields.URLField object>, 'doDimPrevRoundColors': <django.forms.fields.BooleanField object>, 'doUseDescriptionInsteadOfTimeline': <django.forms.fields.BooleanField object>, 'eliminationBarColor': <django.forms.fields.IntegerField object>, 'excludeFinalWinnerAndEliminatedCandidate': <django.forms.fields.BooleanField object>, 'hideDecimals': <django.forms.fields.BooleanField object>, 'hideSankey': <django.forms.fields.BooleanField object>, 'hideTabular': <django.forms.fields.BooleanField object>, 'isPreferentialBlock': <django.forms.fields.BooleanField object>, 'jsonFile': <django.forms.fields.FileField object>, 'onlyShowWinnersTabular': <django.forms.fields.BooleanField object>, 'rotateNames': <django.forms.fields.BooleanField object>, 'showRoundNumbersOnSankey': <django.forms.fields.BooleanField object>, 'textForWinner': <django.forms.fields.IntegerField object>}
- declared_fields = {'colorTheme': <django.forms.fields.IntegerField object>, 'eliminationBarColor': <django.forms.fields.IntegerField object>, 'textForWinner': <django.forms.fields.IntegerField object>}
- property media
Return all media required to render the widgets on this form.
JS Utils
A helper function for javascript-generating python
- visualizer.jsUtils.approx_length(stringToMeasure)
c/o https://stackoverflow.com/a/16008023/1057105 - measure the approximate pixels of the given string
Models
The django object models
- class visualizer.models.ColorTheme(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
IntegerChoices
Describes the status of movie generation for this model
- ALTERNATING = 2
- PURPLE_TO_ORANGE = 1
- RAINBOW = 0
- class visualizer.models.EliminationBarColor(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
IntegerChoices
Describes the status of movie generation for this model
- GRAY = 0
- HIDDEN = 1
- LAST_ROUND_COLOR = 2
- class visualizer.models.HomepageFeaturedElection(*args, **kwargs)
Bases:
Model
Represents a single link on the homepage list of featured elections.
- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- column
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parent
is aForwardManyToOneDescriptor
instance.
- column_id
- id
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- jsonConfig
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parent
is aForwardManyToOneDescriptor
instance.
- jsonConfig_id
- objects = <django.db.models.manager.Manager object>
- order
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- title
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- class visualizer.models.HomepageFeaturedElectionColumn(*args, **kwargs)
Bases:
Model
Represents a column of links on the homepage.
- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- id
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- links_in_column
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Parent.children
is aReverseManyToOneDescriptor
instance.Most of the implementation is delegated to a dynamically defined manager class built by
create_forward_many_to_many_manager()
defined below.
- objects = <django.db.models.manager.Manager object>
- order
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- title
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- class visualizer.models.JsonConfig(*args, **kwargs)
Bases:
Model
A Json file representing a single election, and its configuration
- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- areResultsCertified
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- candidateSidecarFile
The descriptor for the file attribute on the model instance. Return a FieldFile when accessed so you can write code like:
>>> from myapp.models import MyModel >>> instance = MyModel.objects.get(pk=1) >>> instance.file.size
Assign a file object on assignment so you can do:
>>> with open('/path/to/hello.world') as f: ... instance.file = File(f)
- colorTheme
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- dataSourceURL
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- detail_views = ('visualizer.views.Visualize',)
- doDimPrevRoundColors
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- doUseDescriptionInsteadOfTimeline
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- electionpage_set
Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.
In the example:
class Pizza(Model): toppings = ManyToManyField(Topping, related_name='pizzas')
Pizza.toppings
andTopping.pizzas
areManyToManyDescriptor
instances.Most of the implementation is delegated to a dynamically defined manager class built by
create_forward_many_to_many_manager()
defined below.
- eliminationBarColor
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- excludeFinalWinnerAndEliminatedCandidate
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- get_absolute_url()
Used in the admin panel to have a “Visit Site” link
- classmethod get_all_non_auto_fields()
All editable fields of JsonConfig - must be kept up to date with the list of fields above. (I’m sure there’s a way to do this automatically…)
- classmethod get_all_public()
Returns users whose data can be included in sitemap & index
- get_colorTheme_display(*, field=<django.db.models.fields.IntegerField: colorTheme>)
- get_eliminationBarColor_display(*, field=<django.db.models.fields.IntegerField: eliminationBarColor>)
- get_movieGenerationStatus_display(*, field=<django.db.models.fields.IntegerField: movieGenerationStatus>)
- get_next_by_uploadedAt(*, field=<django.db.models.fields.DateTimeField: uploadedAt>, is_next=True, **kwargs)
- get_previous_by_uploadedAt(*, field=<django.db.models.fields.DateTimeField: uploadedAt>, is_next=False, **kwargs)
- get_textForWinner_display(*, field=<django.db.models.fields.IntegerField: textForWinner>)
- hideDecimals
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- hideSankey
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- hideTabular
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- id
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- isPreferentialBlock
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- jsonFile
The descriptor for the file attribute on the model instance. Return a FieldFile when accessed so you can write code like:
>>> from myapp.models import MyModel >>> instance = MyModel.objects.get(pk=1) >>> instance.file.size
Assign a file object on assignment so you can do:
>>> with open('/path/to/hello.world') as f: ... instance.file = File(f)
- movieGenerationStatus
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- movieHorizontal
Accessor to the related object on the forward side of a one-to-one relation.
In the example:
class Restaurant(Model): place = OneToOneField(Place, related_name='restaurant')
Restaurant.place
is aForwardOneToOneDescriptor
instance.
- movieHorizontal_id
- movieVertical
Accessor to the related object on the forward side of a one-to-one relation.
In the example:
class Restaurant(Model): place = OneToOneField(Place, related_name='restaurant')
Restaurant.place
is aForwardOneToOneDescriptor
instance.
- movieVertical_id
- multiscraper
Accessor to the related object on the reverse side of a one-to-one relation.
In the example:
class Restaurant(Model): place = OneToOneField(Place, related_name='restaurant')
Place.restaurant
is aReverseOneToOneDescriptor
instance.
- numCandidates
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- numRounds
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- objects = <django.db.models.manager.Manager object>
- onlyShowWinnersTabular
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- owner
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parent
is aForwardManyToOneDescriptor
instance.
- owner_id
- rawDownloadedBy
Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.
In the example:
class Pizza(Model): toppings = ManyToManyField(Topping, related_name='pizzas')
Pizza.toppings
andTopping.pizzas
areManyToManyDescriptor
instances.Most of the implementation is delegated to a dynamically defined manager class built by
create_forward_many_to_many_manager()
defined below.
- rotateNames
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- save(*args, **kwargs)
Save the current instance. Override this in a subclass if you want to control the saving process.
The ‘force_insert’ and ‘force_update’ parameters can be used to insist that the “save” must be an SQL insert or update (or equivalent for non-SQL backends), respectively. Normally, they should not be set.
- scraper
Accessor to the related object on the reverse side of a one-to-one relation.
In the example:
class Restaurant(Model): place = OneToOneField(Place, related_name='restaurant')
Place.restaurant
is aReverseOneToOneDescriptor
instance.
- showRoundNumbersOnSankey
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- slug
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- textForWinner
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- title
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- uploadedAt
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- class visualizer.models.MovieGenerationStatuses(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
IntegerChoices
Describes the status of movie generation for this model
- COMPLETE = 4
- FAILED = 5
- LANDSCAPE_COMPLETE = 3
- NOT_REQUESTED = 0
- NOT_STARTED = 1
- PICKED_UP_BY_TASK = 2
Tests
URLs
URLs for the primary upload and visualization app
Views
The django views file
- class visualizer.views.BallotpediaViewSet(*args, **kwargs)
Bases:
LoggingMixin
,ModelViewSet
API endpoint with all ballotpedia fields
- basename = None
- description = None
- detail = None
- name = None
- perform_create(serializer)
- permission_classes = [<class 'accounts.permissions.HasAPIAccess'>, <class 'accounts.permissions.IsOwnerOrReadOnly'>]
- queryset
- serializer_class
alias of
BallotpediaSerializer
- suffix = None
- class visualizer.views.DownloadRawData(**kwargs)
Bases:
LoginRequiredMixin
,DetailView
Download raw data - don’t just share the presigned AWS URL, we want a fresh URL for each download.
- get_context_data(**kwargs)
Insert the single object into the context dict.
- login_url = 'login'
- model
alias of
JsonConfig
- redirect_field_name = 'redirect_to'
- template_name = 'visualizer/rawdata.html'
- class visualizer.views.Index(**kwargs)
Bases:
TemplateView
The homepage
- build_path = 'index.html'
- get_context_data(**kwargs)
- template_name = 'visualizer/index.html'
- class visualizer.views.JsonOnlyViewSet(*args, **kwargs)
Bases:
LoggingMixin
,ModelViewSet
API endpoint that allows tabulated JSONs to be viewed or edited.
- basename = None
- description = None
- detail = None
- name = None
- perform_create(serializer)
- permission_classes = [<class 'accounts.permissions.HasAPIAccess'>, <class 'accounts.permissions.IsOwnerOrReadOnly'>]
- queryset
- serializer_class
alias of
JsonOnlySerializer
- suffix = None
- class visualizer.views.Oembed(**kwargs)
Bases:
View
The oembed protocol, pointing to VisualizeEmbedded
- dispatch(request, *args, **kwargs)
- get(request)
Overriding the getter for this class-based view
- class visualizer.views.Upload(**kwargs)
Bases:
LoginRequiredMixin
,CreateView
The upload page
- build_path = 'upload.html'
- form_class
alias of
UploadForm
- form_invalid(form)
If the form is invalid, render the invalid form.
- form_valid(form)
If the form is valid, save the associated model.
- include = ['jsonFile', 'candidateSidecarFile', 'rotateNames', 'showRoundNumbersOnSankey', 'onlyShowWinnersTabular', 'doUseDescriptionInsteadOfTimeline', 'isPreferentialBlock', 'hideSankey', 'hideTabular', 'doDimPrevRoundColors', 'excludeFinalWinnerAndEliminatedCandidate', 'hideDecimals', 'colorTheme', 'eliminationBarColor', 'dataSourceURL', 'areResultsCertified', 'textForWinner']
- login_url = 'login'
- model
alias of
JsonConfig
- redirect_field_name = 'redirect_to'
- success_url = 'v/{slug}'
- template_name = 'visualizer/uploadFile.html'
- class visualizer.views.UploadByDataTable(**kwargs)
Bases:
Upload
Upload form when using the datatables input
- form_class
alias of
UploadByDataTableForm
- class visualizer.views.UserViewSet(*args, **kwargs)
Bases:
LoggingMixin
,ReadOnlyModelViewSet
API endpoint that allows you to view but not edit Users.
- basename = None
- description = None
- detail = None
- name = None
- permission_classes = [<class 'rest_framework.permissions.IsAdminUser'>]
- queryset
- serializer_class
alias of
UserSerializer
- suffix = None
- class visualizer.views.ValidateDataEntry(**kwargs)
Bases:
LoginRequiredMixin
,View
Validation AJAX view: would the current input succeed in creating a graph?
- post(request)
Doesn’t render a webpage - just text
- class visualizer.views.Visualize(**kwargs)
Bases:
DetailView
Visualizing a single JsonConfig
- get(request, *args, **kwargs)
- get_context_data(**kwargs)
Insert the single object into the context dict.
- model
alias of
JsonConfig
- template_name = 'visualizer/visualize.html'
- class visualizer.views.VisualizeBallotpedia(**kwargs)
Bases:
DetailView
The embedded ballotpedia visualization
- dispatch(request, *args, **kwargs)
- get(request, *args, **kwargs)
- get_context_data(**kwargs)
Insert the single object into the context dict.
- model
alias of
JsonConfig
- template_name = 'visualizer/visualize-ballotpedia.html'
- class visualizer.views.VisualizeEmbedded(**kwargs)
Bases:
DetailView
The embedded visualization, to be used in an iframe.
- dispatch(request, *args, **kwargs)
- get(request, *args, **kwargs)
- get_context_data(**kwargs)
Insert the single object into the context dict.
- model
alias of
JsonConfig
- template_name = 'visualizer/visualize-embedded.html'
- class visualizer.views.VisualizeEmbedly(**kwargs)
Bases:
RedirectView
VisualizeEmbedded, but without any custom arguments so it can be supported by embedly. Since embedly doesn’t allow custom arguments, we cannot use ?vistype in oembed. We have replaced this with /vo/slug/vistype instead,
Further, we simplify vistype so it reads more easily. The changed vistypes are: barchart-interactive –> bar barchart-fixed –> bar-static tabular-candidate-by-round –> table tabular-by-round-interactive –> table-by-round tabular-by-round –> table-by-round-static tabular-by-candidate –> table-by-candidate
- get_redirect_url(*args, **kwargs)
Return the URL redirect to. Keyword arguments from the URL pattern match generating the redirect request are provided as kwargs to this method.
- pattern_name = 'visualizeEmbedded'
- permanent = True