featured app admin tool (bug 754441)
This commit is contained in:
Родитель
fab67d669d
Коммит
33e90a82c4
|
@ -295,7 +295,7 @@ class BaseAjaxSearch(object):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, request, excluded_ids=[]):
|
||||
def __init__(self, request, excluded_ids=()):
|
||||
self.request = request
|
||||
self.excluded_ids = excluded_ids
|
||||
self.src = getattr(self, 'src', None)
|
||||
|
@ -369,6 +369,19 @@ class PersonaSuggestionsAjax(SearchSuggestionsAjax):
|
|||
|
||||
class WebappSuggestionsAjax(SearchSuggestionsAjax):
|
||||
types = [amo.ADDON_WEBAPP]
|
||||
fields = {'id': 'id',
|
||||
'name': 'name'
|
||||
}
|
||||
|
||||
def __init__(self, request, excluded_ids=(), category=None):
|
||||
self.category = category
|
||||
SearchSuggestionsAjax.__init__(self, request, excluded_ids)
|
||||
|
||||
def queryset(self):
|
||||
res = SearchSuggestionsAjax.queryset(self)
|
||||
if self.category:
|
||||
res = res.filter(category__in=[self.category])
|
||||
return res
|
||||
|
||||
|
||||
@json_view
|
||||
|
|
|
@ -5,7 +5,8 @@ function registerAddonAutocomplete(node) {
|
|||
width: 300,
|
||||
source: function(request, response) {
|
||||
$.getJSON($(node).attr('data-src'), {
|
||||
q: request.term
|
||||
q: request.term,
|
||||
category: $("#categories").val()
|
||||
}, response);
|
||||
},
|
||||
focus: function(event, ui) {
|
||||
|
@ -13,17 +14,8 @@ function registerAddonAutocomplete(node) {
|
|||
return false;
|
||||
},
|
||||
select: function(event, ui) {
|
||||
$(node).val(ui.item.name).attr('data-id', ui.item.id);
|
||||
var current = template(
|
||||
'<a href="{url}" target="_blank"><img src="{icon}"> {name}</a>');
|
||||
$td.find('.current-webapp').show().html(current({
|
||||
url: ui.item.url,
|
||||
icon: ui.item.icon,
|
||||
name: ui.item.name
|
||||
}));
|
||||
$td.find('input[type=hidden]').val(ui.item.id);
|
||||
node.val('');
|
||||
node.hide();
|
||||
updateAppsList($("#categories"),
|
||||
ui.item.id);
|
||||
return false;
|
||||
}
|
||||
}).data('autocomplete')._renderItem = function(ul, item) {
|
||||
|
@ -33,19 +25,55 @@ function registerAddonAutocomplete(node) {
|
|||
}
|
||||
|
||||
function newAddonSlot(id) {
|
||||
var $tbody = $("#" + id + "-webapps");
|
||||
var $tbody = $("#featured-webapps");
|
||||
var $form = $tbody.next().children("tr").clone();
|
||||
var $input = $form.find('input.placeholder');
|
||||
registerAddonAutocomplete($input);
|
||||
$form.find('input[type=hidden]').attr(
|
||||
"name", $tbody.children().length + "-" + id +"-webapp");
|
||||
$tbody.append($form);
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$("#home-webapps, #category-webapps").delegate(
|
||||
'.remove', 'click', _pd(function() {$(this).closest('tr').remove();}));
|
||||
function showAppsList(cat) {
|
||||
return appslistXHR('GET', {
|
||||
category: cat.val()
|
||||
})};
|
||||
|
||||
$('#home-add').click(_pd(function() { newAddonSlot("home"); }));
|
||||
$('#category-add').click(_pd(function() { newAddonSlot("category"); }));
|
||||
function updateAppsList(cat, newItem) {
|
||||
return appslistXHR('POST', {
|
||||
category: cat.val(),
|
||||
add: newItem
|
||||
})};
|
||||
|
||||
function deleteFromAppsList(cat, oldItem) {
|
||||
return appslistXHR('POST', {
|
||||
category: cat.val(),
|
||||
delete: oldItem
|
||||
})};
|
||||
|
||||
function appslistXHR(verb, data) {
|
||||
var appslist = $("#featured-webapps");
|
||||
var q = $.ajax({type: verb, url: appslist.data("src"), data: data});
|
||||
q.then(function (data) {
|
||||
appslist.html(data);
|
||||
});
|
||||
return q;
|
||||
};
|
||||
|
||||
$(document).ready(function(){
|
||||
$("#featured-webapps").delegate(
|
||||
'.remove', 'click', _pd(function() {
|
||||
deleteFromAppsList($("#categories"),
|
||||
$(this).data("id"));
|
||||
}));
|
||||
var categories = $("#categories");
|
||||
var appslist = $("#featured-webapps");
|
||||
var p = $.ajax({type: 'GET',
|
||||
url: categories.data("src")});
|
||||
p.then(function(data) {
|
||||
categories.html(data);
|
||||
showAppsList(categories);
|
||||
});
|
||||
categories.change(function (e) {
|
||||
showAppsList(categories);
|
||||
});
|
||||
$('#featured-add').click(_pd(function() { newAddonSlot(); }));
|
||||
});
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
CREATE TABLE `zadmin_featuredapp` (
|
||||
`id` int(11) unsigned AUTO_INCREMENT NOT NULL PRIMARY KEY,
|
||||
`app_id` integer NOT NULL,
|
||||
`category_id` int(11) unsigned,
|
||||
`is_sponsor` bool NOT NULL,
|
||||
FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`)
|
||||
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
|
|
@ -13,6 +13,8 @@ from mkt.search.forms import DEVICE_CHOICES_IDS
|
|||
from mkt.webapps.models import Webapp
|
||||
from mkt.webapps.tests.test_views import PaidAppMixin
|
||||
|
||||
from search.tests.test_views import TestAjaxSearch
|
||||
|
||||
|
||||
class SearchBase(amo.tests.ESTestCase):
|
||||
|
||||
|
@ -258,3 +260,39 @@ class TestWebappSearch(PaidAppMixin, SearchBase):
|
|||
# `sort=price` should be removed if `price=free` is in querystring.
|
||||
r = self.client.get(url, {'price': 'free', 'sort': 'price'})
|
||||
self.assertRedirects(r, urlparams(url, price='free'))
|
||||
|
||||
|
||||
class SuggestionsTests(TestAjaxSearch):
|
||||
|
||||
def check_suggestions(self, url, params, addons=()):
|
||||
r = self.client.get(url + '?' + params)
|
||||
eq_(r.status_code, 200)
|
||||
data = json.loads(r.content)
|
||||
data.sort(key=lambda x: x['id'])
|
||||
addons.sort(key=lambda x: x.id)
|
||||
eq_(len(data), len(addons))
|
||||
for got, expected in zip(data, addons):
|
||||
eq_(int(got['id']), expected.id)
|
||||
eq_(got['name'], unicode(expected.name))
|
||||
|
||||
def test_webapp_search(self):
|
||||
url = reverse('search.apps_ajax')
|
||||
c1 = Category.objects.create(name='groovy',
|
||||
type=amo.ADDON_WEBAPP)
|
||||
c2 = Category.objects.create(name='awesome',
|
||||
type=amo.ADDON_WEBAPP)
|
||||
g1 = Webapp.objects.create(status=amo.STATUS_PUBLIC,
|
||||
name='groovy app 1',
|
||||
type=amo.ADDON_WEBAPP)
|
||||
a2 = Webapp.objects.create(status=amo.STATUS_PUBLIC,
|
||||
name='awesome app 2',
|
||||
type=amo.ADDON_WEBAPP)
|
||||
AddonCategory.objects.create(category=c1, addon=g1)
|
||||
AddonCategory.objects.create(category=c2, addon=a2)
|
||||
self.client.login(username='admin@mozilla.com', password='password')
|
||||
for a in Webapp.objects.all():
|
||||
a.save()
|
||||
self.refresh()
|
||||
self.check_suggestions(url, "q=app&category=", addons=[g1, a2])
|
||||
self.check_suggestions(url, "q=app&category=%d" % c1.id, addons=[g1])
|
||||
self.check_suggestions(url, "q=app&category=%d" % c2.id, addons=[a2])
|
||||
|
|
|
@ -191,4 +191,7 @@ def app_search(request):
|
|||
|
||||
@json_view
|
||||
def ajax_search(request):
|
||||
return WebappSuggestionsAjax(request).items
|
||||
category = request.GET.get('category', None) or None
|
||||
if category:
|
||||
category = int(category)
|
||||
return WebappSuggestionsAjax(request, category=category).items
|
||||
|
|
|
@ -182,7 +182,7 @@ def admin_site_links():
|
|||
return {
|
||||
'addons': [
|
||||
('Search for apps by name or id', reverse('zadmin.addon-search')),
|
||||
('Featured add-ons', reverse('admin.featured_apps')),
|
||||
('Featured add-ons', reverse('zadmin.featured_apps')),
|
||||
('Name blocklist', reverse('zadmin.addon-name-blocklist')),
|
||||
('Fake mail', reverse('zadmin.mail')),
|
||||
('Flagged reviews', reverse('zadmin.flagged')),
|
||||
|
|
|
@ -12,8 +12,6 @@ from apps.users.urls import (detail_patterns as user_detail_patterns,
|
|||
from mkt.account.urls import (purchases_patterns, settings_patterns,
|
||||
users_patterns as mkt_users_patterns)
|
||||
from mkt.developers.views import login
|
||||
from mkt.zadmin.views import featured_apps_admin
|
||||
|
||||
|
||||
admin.autodiscover()
|
||||
|
||||
|
@ -92,10 +90,6 @@ urlpatterns = patterns('',
|
|||
# Paypal, needed for IPNs only.
|
||||
('^services/', include('paypal.urls')),
|
||||
|
||||
# Featured apps selector.
|
||||
url('^admin/apps/featured$', featured_apps_admin,
|
||||
name='admin.featured_apps'),
|
||||
|
||||
# AMO admin (not django admin).
|
||||
('^admin/', include('zadmin.urls')),
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
from django.db import models
|
||||
|
||||
from addons.models import Category
|
||||
from mkt.webapps.models import Webapp
|
||||
|
||||
|
||||
class FeaturedApp(models.Model):
|
||||
app = models.ForeignKey(Webapp, null=False)
|
||||
category = models.ForeignKey(Category, null=True)
|
||||
is_sponsor = models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
db_table = 'zadmin_featuredapp'
|
|
@ -0,0 +1,28 @@
|
|||
{% block content %}
|
||||
{% for row in apps -%}
|
||||
<tr>
|
||||
<td>
|
||||
<table>
|
||||
<tr>
|
||||
<td><img src="{{ row.app.icon_url }}"></td>
|
||||
<td>{{ row.app.name }}</td>
|
||||
<td>{% for dt in row.app.device_types %}
|
||||
{{ dt }}
|
||||
{% endfor %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% if row.app.promo %}
|
||||
<a href="{{ row.app.get_dev_url() }}">Manage featured graphics</a>
|
||||
{% else %}
|
||||
<a href="{{ row.app.get_dev_url() }}">No featured graphics</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{% if row.is_sponsor %}Sponsored{% else %}Not sponsored{% endif %}</td>
|
||||
<td>Locale etc</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td><input type="hidden"><a class="remove" data-id="{{ row.app.id }}">×</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,6 @@
|
|||
{% block content %}
|
||||
<option value="">Home Page ({{ homecount }})</option>
|
||||
{% for opt in categories -%}
|
||||
<option value="{{ opt['id'] }}">{{ opt['name'] }} ({{ opt['count'] }})</option>
|
||||
{%- endfor %}
|
||||
{% endblock %}
|
|
@ -4,56 +4,52 @@
|
|||
{% block js %}
|
||||
{{ super() }}
|
||||
<script src="{{ media('js/mkt/admin_featuredapp.js') }}"></script>
|
||||
<script type="text/template" id="featured-app-template">
|
||||
<tr><td>
|
||||
<div class="current-webapp js-hidden" style="display: block;">
|
||||
<div>
|
||||
<a target="_blank" href="<%= app_url %>">
|
||||
<img src="<%= featured_graphic %>"><span><%= _.escape(app_name) %></span></a><%= format_support %>
|
||||
</div>
|
||||
<div>
|
||||
<span class="sponsor"><%= is_sponsor %></span> <span class="localepicker"><%= locale %></span>
|
||||
</div>
|
||||
<a class="remove">×</a>
|
||||
</div>
|
||||
</td></tr>
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% set title = 'Feature Manager' %}
|
||||
{% block title %}{{ mkt_page_title(title) }}{% endblock %}
|
||||
|
||||
{% macro appsform(id, apps) %}
|
||||
<table>
|
||||
<thead>
|
||||
<th>App</th>
|
||||
<th class="js-hidden">Delete</th>
|
||||
</thead>
|
||||
<tbody id="{{ id }}-webapps">
|
||||
{% for idx, app in apps %}
|
||||
<tr><td>
|
||||
<div class="current-webapp js-hidden" style="display: block;">
|
||||
<a target="_blank" href="{{ app.get_url_path() }}">
|
||||
<img src="{{ app.icon_url }}"> {{ app.name }}</a>
|
||||
</div>
|
||||
<input type="hidden" name="{{ idx }}-{{ id }}-webapp" value="{{ app.id }}">
|
||||
<a class="remove">×</a>
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot class="hidden">
|
||||
<tr><td>
|
||||
<div class="current-webapp js-hidden" style="display: block;"></div>
|
||||
<input placeholder="{{ _('Enter the name of the webapp to include') }}"
|
||||
class="placeholder addon-ac large" data-src="{{ url('search.apps_ajax') }}">
|
||||
<input type="hidden"><a class="remove">×</a>
|
||||
</td></tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
{% endmacro %}
|
||||
|
||||
{% block content %}
|
||||
<h2>{{ title }}</h2>
|
||||
|
||||
<form method="post">
|
||||
{{ csrf() }}
|
||||
<h3>Home Featured</h3>
|
||||
{{ appsform('home', home_featured) }}
|
||||
<p><a href="#" id="home-add">Add an app</a></p>
|
||||
<p>
|
||||
<button type="submit" name="home_submit">Save Changes</button> or <a href="">Cancel</a>
|
||||
</p>
|
||||
<h3>Category Featured</h3>
|
||||
{{ appsform('category', category_featured) }}
|
||||
<p><a href="#" id="category-add">Add an app</a></p>
|
||||
<p>
|
||||
<button type="submit" name="category_submit">Save Changes</button> or <a href="">Cancel</a>
|
||||
</p>
|
||||
<h3>Featured Apps</h3>
|
||||
Section: <select id="categories"
|
||||
data-src="{{ url('zadmin.featured_categories_ajax') }}"
|
||||
></select>
|
||||
<table>
|
||||
<thead>
|
||||
<th>App</th>
|
||||
<th>Delete</th>
|
||||
</thead>
|
||||
<tbody id="featured-webapps"
|
||||
data-src="{{ url('zadmin.featured_apps_ajax') }}">
|
||||
</tbody>
|
||||
<tfoot class="hidden">
|
||||
<tr><td>
|
||||
<div class="current-webapp js-hidden" style="display: block;"></div>
|
||||
<input placeholder="{{ _('Enter the name of the webapp to include') }}"
|
||||
class="placeholder addon-ac large"
|
||||
data-src="{{ url('search.apps_ajax') }}">
|
||||
<input type="hidden"><a class="remove">×</a>
|
||||
</td></tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<p><a href="#" id="featured-add">Add an app</a></p>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
from nose.tools import eq_
|
||||
from pyquery import PyQuery as pq
|
||||
|
||||
import amo
|
||||
import amo.tests
|
||||
from amo.utils import urlparams
|
||||
from amo.urlresolvers import reverse
|
||||
|
||||
from addons.models import Category, AddonCategory
|
||||
from mkt.webapps.models import Webapp
|
||||
from mkt.zadmin.models import FeaturedApp
|
||||
|
||||
|
||||
class TestFeaturedApps(amo.tests.TestCase):
|
||||
fixtures = ['base/users']
|
||||
def setUp(self):
|
||||
self.c1 = Category.objects.create(name='awesome',
|
||||
type=amo.ADDON_WEBAPP)
|
||||
self.c2 = Category.objects.create(name='groovy',
|
||||
type=amo.ADDON_WEBAPP)
|
||||
|
||||
self.a1 = Webapp.objects.create(status=amo.STATUS_PUBLIC,
|
||||
name='awesome app 1',
|
||||
type=amo.ADDON_WEBAPP)
|
||||
self.a2 = Webapp.objects.create(status=amo.STATUS_PUBLIC,
|
||||
name='awesome app 2',
|
||||
type=amo.ADDON_WEBAPP)
|
||||
self.g1 = Webapp.objects.create(status=amo.STATUS_PUBLIC,
|
||||
name='groovy app 1',
|
||||
type=amo.ADDON_WEBAPP)
|
||||
self.s1 = Webapp.objects.create(status=amo.STATUS_PUBLIC,
|
||||
name='splendid app 1',
|
||||
type=amo.ADDON_WEBAPP)
|
||||
AddonCategory.objects.create(category=self.c1, addon=self.a1)
|
||||
AddonCategory.objects.create(category=self.c1, addon=self.a2)
|
||||
|
||||
AddonCategory.objects.create(category=self.c2, addon=self.g1)
|
||||
|
||||
AddonCategory.objects.create(category=self.c1, addon=self.s1)
|
||||
AddonCategory.objects.create(category=self.c2, addon=self.s1)
|
||||
|
||||
self.client.login(username='admin@mozilla.com', password='password')
|
||||
self.url = reverse('zadmin.featured_apps_ajax')
|
||||
|
||||
def test_get_featured_apps(self):
|
||||
r = self.client.get(urlparams(self.url, category=self.c1.id))
|
||||
assert not r.content
|
||||
|
||||
f1 = FeaturedApp.objects.create(app=self.a1, category=self.c1)
|
||||
f2 = FeaturedApp.objects.create(app=self.s1, category=self.c2, is_sponsor=True)
|
||||
r = self.client.get(urlparams(self.url, category=self.c1.id))
|
||||
doc = pq(r.content)
|
||||
eq_(len(doc), 1)
|
||||
eq_(doc('table td').eq(1).text(), 'awesome app 1')
|
||||
eq_(doc('table td').eq(4).text(), 'Not sponsored')
|
||||
|
||||
r = self.client.get(urlparams(self.url, category=self.c2.id))
|
||||
doc = pq(r.content)
|
||||
eq_(len(doc), 1)
|
||||
eq_(doc('table td').eq(1).text(), 'splendid app 1')
|
||||
eq_(doc('table td').eq(4).text(), 'Sponsored')
|
||||
|
||||
|
||||
def test_get_categories(self):
|
||||
url = reverse('zadmin.featured_categories_ajax')
|
||||
FeaturedApp.objects.create(app=self.a1, category=self.c1)
|
||||
FeaturedApp.objects.create(app=self.a2, category=self.c1)
|
||||
FeaturedApp.objects.create(app=self.a2, category=None)
|
||||
r = self.client.get(url)
|
||||
doc = pq(r.content)
|
||||
eq_(set(pq(x).text() for x in doc[0]),
|
||||
set(['Home Page (1)', 'groovy (0)', 'awesome (2)']))
|
||||
|
||||
def test_add_featured_app(self):
|
||||
self.client.post(self.url,
|
||||
{'category': '',
|
||||
'add': self.a1.id})
|
||||
assert FeaturedApp.objects.filter(app=self.a1.id,
|
||||
category=None).exists()
|
||||
|
||||
self.client.post(self.url,
|
||||
{'category': self.c1.id,
|
||||
'add': self.a1.id})
|
||||
assert FeaturedApp.objects.filter(app=self.a1,
|
||||
category=self.c1).exists()
|
||||
|
||||
def test_delete_featured_app(self):
|
||||
FeaturedApp.objects.create(app=self.a1, category=None)
|
||||
FeaturedApp.objects.create(app=self.a1, category=self.c1)
|
||||
self.client.post(self.url,
|
||||
{'category': '',
|
||||
'delete': self.a1.id})
|
||||
assert not FeaturedApp.objects.filter(app=self.a1,
|
||||
category=None).exists()
|
||||
assert FeaturedApp.objects.filter(app=self.a1,
|
||||
category=self.c1).exists()
|
||||
FeaturedApp.objects.create(app=self.a1, category=None)
|
||||
self.client.post(self.url,
|
||||
{'category': self.c1.id,
|
||||
'delete': self.a1.id})
|
||||
assert not FeaturedApp.objects.filter(app=self.a1,
|
||||
category=self.c1).exists()
|
|
@ -2,7 +2,14 @@ from django.conf.urls.defaults import patterns, url
|
|||
|
||||
from . import views
|
||||
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url('^ecosystem$', views.ecosystem, name='mkt.zadmin.ecosystem')
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
url('^ecosystem$', views.ecosystem, name='mkt.zadmin.ecosystem'),
|
||||
# Featured apps selector.
|
||||
url('^apps/featured$', views.featured_apps_admin,
|
||||
name='zadmin.featured_apps'),
|
||||
url('^apps/featured_ajax$', views.featured_apps_ajax,
|
||||
name='zadmin.featured_apps_ajax'),
|
||||
url('^apps/featured_categories_ajax$', views.featured_categories_ajax,
|
||||
name='zadmin.featured_categories_ajax'),
|
||||
)
|
||||
|
|
|
@ -4,45 +4,24 @@ from django.contrib import admin
|
|||
from django.shortcuts import redirect
|
||||
from django.db import transaction
|
||||
|
||||
import amo
|
||||
from amo import messages
|
||||
from amo.decorators import write
|
||||
from amo.decorators import write, json_view
|
||||
from amo.urlresolvers import reverse
|
||||
from addons.models import Category, AddonCategory
|
||||
from bandwagon.models import CollectionAddon
|
||||
|
||||
from mkt.ecosystem.tasks import refresh_mdn_cache, tutorials
|
||||
from mkt.ecosystem.models import MdnCache
|
||||
from mkt.webapps.models import Webapp
|
||||
from mkt.zadmin.models import FeaturedApp
|
||||
|
||||
|
||||
@transaction.commit_on_success
|
||||
@write
|
||||
@admin.site.admin_view
|
||||
def featured_apps_admin(request):
|
||||
home_collection = Webapp.featured_collection('home')
|
||||
category_collection = Webapp.featured_collection('category')
|
||||
|
||||
if request.POST:
|
||||
if 'home_submit' in request.POST:
|
||||
coll = home_collection
|
||||
rowid = 'home'
|
||||
elif 'category_submit' in request.POST:
|
||||
coll = category_collection
|
||||
rowid = 'category'
|
||||
existing = set(coll.addons.values_list('id', flat=True))
|
||||
requested = set(int(request.POST[k])
|
||||
for k in sorted(request.POST.keys())
|
||||
if k.endswith(rowid + '-webapp'))
|
||||
CollectionAddon.objects.filter(collection=coll,
|
||||
addon__in=(existing - requested)).delete()
|
||||
for id in requested - existing:
|
||||
CollectionAddon.objects.create(collection=coll, addon_id=id)
|
||||
messages.success(request, 'Changes successfully saved.')
|
||||
return redirect(reverse('admin.featured_apps'))
|
||||
|
||||
return jingo.render(request, 'zadmin/featuredapp.html', {
|
||||
'home_featured': enumerate(home_collection.addons.all()),
|
||||
'category_featured': enumerate(category_collection.addons.all())
|
||||
})
|
||||
return jingo.render(request, 'zadmin/featuredapp.html')
|
||||
|
||||
|
||||
@admin.site.admin_view
|
||||
|
@ -58,3 +37,41 @@ def ecosystem(request):
|
|||
}
|
||||
|
||||
return jingo.render(request, 'zadmin/ecosystem.html', ctx)
|
||||
|
||||
|
||||
@admin.site.admin_view
|
||||
def featured_apps_ajax(request):
|
||||
if request.GET:
|
||||
cat = request.GET.get('category', None) or None
|
||||
if cat:
|
||||
cat = int(cat)
|
||||
elif request.POST:
|
||||
cat = request.POST.get('category', None) or None
|
||||
if cat:
|
||||
cat = int(cat)
|
||||
deleteid = request.POST.get('delete', None)
|
||||
if deleteid:
|
||||
FeaturedApp.objects.filter(category__id=cat,
|
||||
app__id=int(deleteid)).delete()
|
||||
appid = request.POST.get('add', None)
|
||||
if appid:
|
||||
FeaturedApp.objects.get_or_create(category_id=cat,
|
||||
app_id=int(appid))
|
||||
else:
|
||||
cat = None
|
||||
|
||||
apps = FeaturedApp.objects.filter(category__id=cat)
|
||||
return jingo.render(request, 'zadmin/featured_apps_ajax.html',
|
||||
{'apps': apps})
|
||||
|
||||
@admin.site.admin_view
|
||||
def featured_categories_ajax(request):
|
||||
cats = Category.objects.filter(type=amo.ADDON_WEBAPP)
|
||||
return jingo.render(request, 'zadmin/featured_categories_ajax.html', {
|
||||
'homecount': FeaturedApp.objects.filter(
|
||||
category=None).count(),
|
||||
'categories': [{
|
||||
'name': cat.name,
|
||||
'id': cat.pk,
|
||||
'count': FeaturedApp.objects.filter(category=cat).count()
|
||||
} for cat in cats]})
|
||||
|
|
Загрузка…
Ссылка в новой задаче