Skip to content
This repository has been archived by the owner on Jan 15, 2019. It is now read-only.

Use RawGenericKey for related_content #13

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@ armstrong.apps.related_content
==============================
Provides mechanism for relating content to other models

You can use ``armstrong.apps.related_content`` to link two separate models
together through a ``GenericForeignKey`` for the ``source`` and the
``destination``. You can further organize the relationship with
``RelatedType`` (think: "articles", "images", "external_links", and so on) and
all relationships are ordered.


Usage
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was a merge fail looking at the history.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it was

-----
You do *not* have to change your models to utilize related content---it exists
Expand Down
19 changes: 14 additions & 5 deletions armstrong/apps/related_content/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
from django.conf import settings
from django.contrib import admin
from django.contrib.contenttypes.generic import GenericTabularInline
from django.forms import widgets as django_widgets

from armstrong.hatband import widgets

from .models import RelatedContent
from .models import RelatedType

from armstrong.hatband.utils import static_url


"""
Setting ARMSTRONG_RELATED_TYPE_DEFAULT_FILTER allows you to specify
Expand All @@ -17,14 +20,19 @@


class RelatedContentInlineForm(forms.ModelForm):

class Media:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should respect ARMSTRONG_ADMIN_PROVIDE_STATIC (see 905d2ae)

js = (
'hatband/js/jquery-ui-1.8.16.min.js',
)

class Meta:
widgets = {
"destination_type": forms.HiddenInput(),
"destination_id": widgets.GenericKeyWidget(
"destination_id": widgets.RawGenericKeyWidget(
object_id_name="destination_id",
content_type_name="destination_type",
),
"order": forms.HiddenInput(),
"order": django_widgets.HiddenInput(),
}


Expand All @@ -33,10 +41,11 @@ class RelatedContentInline(GenericTabularInline):
ct_fk_field = "source_id"

model = RelatedContent
template = "admin/edit_inline/generickey.html"

template = 'admin/edit_inline/related_content.html'
form = RelatedContentInlineForm

extra = 0

def formfield_for_foreignkey(self, *args, **kwargs):
args, kwargs = formfield_for_foreignkey_helper(self, *args, **kwargs)
return super(RelatedContentInline, self).formfield_for_foreignkey(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(function($){
$(document).ready(function(){
$('.inline-related .add-row a').click(function(){
alert('maybe?');
});
});
})(django.jQuery);
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
{% load i18n adminmedia admin_modify %}
<div class="inline-group" id="{{ inline_admin_formset.formset.prefix }}-group">
<div class="tabular inline-related {% if forloop.last %}last-related{% endif %}">
{{ inline_admin_formset.formset.management_form }}
<fieldset class="module">
<h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
{{ inline_admin_formset.formset.non_form_errors }}
<table>
<thead><tr>
{% for field in inline_admin_formset.fields %}
{% if not field.widget.is_hidden %}
<th{% if forloop.first %} colspan="2"{% endif %}{% if field.required %} class="required"{% endif %}>{{ field.label|capfirst }}</th>
{% endif %}
{% endfor %}
{% if inline_admin_formset.formset.can_delete %}<th>{% trans "Delete?" %}</th>{% endif %}
</tr></thead>

<tbody>
{% for inline_admin_form in inline_admin_formset %}
{% if inline_admin_form.form.non_field_errors %}
<tr><td colspan="{{ inline_admin_form|cell_count }}">{{ inline_admin_form.form.non_field_errors }}</td></tr>
{% endif %}
<tr class="{% cycle "row1" "row2" %} {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}{% if forloop.last %} empty-form{% endif %}"
id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
<td class="original">
{% if inline_admin_form.original or inline_admin_form.show_url %}<p>
{% if inline_admin_form.original %} {{ inline_admin_form.original }}{% endif %}
{% if inline_admin_form.show_url %}<a href="../../../r/{{ inline_admin_form.original_content_type_id }}/{{ inline_admin_form.original.id }}/">{% trans "View on site" %}</a>{% endif %}
</p>{% endif %}
{% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
{{ inline_admin_form.fk_field.field }}
{% spaceless %}
{% for fieldset in inline_admin_form %}
{% for line in fieldset %}
{% for field in line %}
{% if field.field.is_hidden %} {{ field.field }} {% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endspaceless %}
</td>
{% for fieldset in inline_admin_form %}
{% for line in fieldset %}
{% for field in line %}
{% if not field.field.is_hidden %}
<td class="{{ field.field.name }}">
{% if field.is_readonly %}
<p>{{ field.contents }}</p>
{% else %}
{{ field.field.errors.as_ul }}
{{ field.field }}
{% endif %}
</td>
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
{% if inline_admin_formset.formset.can_delete %}
<td class="delete">{% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</fieldset>
</div>
</div>


<script type="text/javascript">
(function($) {
$(document).ready(function($) {
var rows = "#{{ inline_admin_formset.formset.prefix }}-group .tabular.inline-related tbody tr";
var alternatingRows = function(row) {
$(rows).not(".add-row").removeClass("row1 row2")
.filter(":even").addClass("row1").end()
.filter(rows + ":odd").addClass("row2");
}
var reinitDateTimeShortCuts = function() {
// Reinitialize the calendar and clock widgets by force
if (typeof DateTimeShortcuts != "undefined") {
$(".datetimeshortcuts").remove();
DateTimeShortcuts.init();
}
}
var updateSelectFilter = function() {
// If any SelectFilter widgets are a part of the new form,
// instantiate a new SelectFilter instance for it.
if (typeof SelectFilter != "undefined"){
$(".selectfilter").each(function(index, value){
var namearr = value.name.split('-');
SelectFilter.init(value.id, namearr[namearr.length-1], false, "{% admin_media_prefix %}");
});
$(".selectfilterstacked").each(function(index, value){
var namearr = value.name.split('-');
SelectFilter.init(value.id, namearr[namearr.length-1], true, "{% admin_media_prefix %}");
});
}
}
var initPrepopulatedFields = function(row) {
row.find('.prepopulated_field').each(function() {
var field = $(this);
var input = field.find('input, select, textarea');
var dependency_list = input.data('dependency_list') || [];
var dependencies = [];
$.each(dependency_list, function(i, field_name) {
dependencies.push('#' + row.find(field_name).find('input, select, textarea').attr('id'));
});
if (dependencies.length) {
input.prepopulate(dependencies, input.attr('maxlength'));
}
});
}
var rawGenericKey = function(row){
armstrong.widgets.raw_generic_key(
row.find('td.destination_type select'),
row.find('td.destination_id input'),
row.find('td.destination_id a')
);
}
var reorder = function(){
$(rows).each(function(idx, el) {
$(el).find("[id$=order]").val(idx);
})
}
$(rows).formset({
prefix: "{{ inline_admin_formset.formset.prefix }}",
addText: "{% blocktrans with inline_admin_formset.opts.verbose_name|title as verbose_name %}Add another {{ verbose_name }}{% endblocktrans %}",
formCssClass: "dynamic-{{ inline_admin_formset.formset.prefix }}",
deleteCssClass: "inline-deletelink",
deleteText: "{% trans "Remove" %}",
emptyCssClass: "empty-form",
removed: alternatingRows,
added: (function(row) {
initPrepopulatedFields(row);
reinitDateTimeShortCuts();
updateSelectFilter();
alternatingRows(row);
rawGenericKey(row);
reorder();
})
});
$(rows).parent().sortable();
$(rows).parent().bind('sortupdate', reorder);
$(rows).parent().bind('sortupdate', alternatingRows);
reorder();
});
})(django.jQuery);
</script>