Projet

Général

Profil

0001-misc-allow-page-with-same-slug-but-different-parents.patch

Frédéric Péters, 08 août 2018 17:27

Télécharger (6,56 ko)

Voir les différences:

Subject: [PATCH] misc: allow page with same slug but different parents (#8521)

 combo/data/models.py   |  2 +-
 combo/manager/forms.py |  2 +-
 combo/manager/views.py | 10 ++++++++++
 combo/public/views.py  | 16 ++++++++++++++--
 tests/test_manager.py  | 42 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 68 insertions(+), 4 deletions(-)
combo/data/models.py
172 172
            i = 1
173 173
            while True:
174 174
                try:
175
                    Page.objects.get(slug=slug)
175
                    Page.objects.get(slug=slug, parent_id=self.parent_id)
176 176
                except ObjectDoesNotExist:
177 177
                    break
178 178
                i += 1
combo/manager/forms.py
38 38
        value = self.cleaned_data.get('slug')
39 39
        if self.instance.slug == value:
40 40
            return value
41
        if Page.objects.filter(slug=value).count() > 0:
41
        if Page.objects.filter(slug=value, parent_id=self.instance.parent_id).count() > 0:
42 42
            raise ValidationError(_('Slug must be unique'), code='unique')
43 43
        return value
44 44

  
combo/manager/views.py
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
import hashlib
17 18
import json
18 19
import os
19 20

  
......
452 453
def page_order(request):
453 454
    new_order = [int(x) for x in request.GET['new-order'].split(',')]
454 455
    moved_page = Page.objects.get(id=request.GET['moved-page-id'])
456
    current_parent_id = moved_page.parent_id
455 457
    if request.GET['moved-page-new-parent']:
456 458
        moved_page.parent_id = request.GET['moved-page-new-parent']
457 459
    else:
458 460
        moved_page.parent_id = None
459 461
    moved_page.save()
462
    slug_conflict = False
460 463
    for page in Page.objects.filter(parent_id=moved_page.parent_id):
461 464
        page.order = new_order.index(page.id)+1
462 465
        page.save()
466
        if moved_page.id != page.id and moved_page.slug == page.slug:
467
            slug_conflict = True
468
    if slug_conflict:
469
        # slug conflict after a page got moved, reload and rename
470
        moved_page = Page.objects.get(id=request.GET['moved-page-id'])
471
        moved_page.slug = moved_page.slug + '-' + hashlib.md5(str(moved_page.id)).hexdigest()[:4]
472
        moved_page.save()
463 473
    return redirect(reverse('combo-manager-homepage'))
464 474

  
465 475

  
combo/public/views.py
350 350
            request.session['visited'] = True
351 351
            return HttpResponseRedirect(settings.COMBO_WELCOME_PAGE_PATH)
352 352

  
353
    slugs = {'parent__'*len(parts) + 'isnull': True}
354
    for i, part in enumerate(reversed(parts)):
355
        slugs['parent__'*i + 'slug'] = part
353 356
    try:
354
        page = Page.objects.get(slug=parts[-1])
357
        page = Page.objects.get(**slugs)
355 358
    except Page.DoesNotExist:
356 359
        if Page.objects.count() == 0 and parts == ['index']:
357 360
            return empty_site(request)
358
        page = None
361
        # maybe the page is a children of /index/, as /index/ is silent the
362
        # page would appear directly under /; this is not a suggested practice.
363
        parts = ['index'] + parts
364
        slugs = {'parent__'*len(parts) + 'isnull': True}
365
        for i, part in enumerate(reversed(parts)):
366
            slugs['parent__'*i + 'slug'] = part
367
        try:
368
            page = Page.objects.get(**slugs)
369
        except Page.DoesNotExist:
370
            page = None
359 371

  
360 372
    if page is None or page.get_online_url() != url:
361 373
        if not url.endswith('/') and settings.APPEND_SLASH:
tests/test_manager.py
222 222
    assert resp.location.endswith('/manage/')
223 223
    assert Page.objects.count() == 0
224 224

  
225
def test_page_reorder(app, admin_user):
226
    Page.objects.all().delete()
227
    page1 = Page(title='One', slug='one', parent=None, order=0, template_name='standard')
228
    page1.save()
229
    page2 = Page(title='Two', slug='two', parent=None, order=1, template_name='standard')
230
    page2.save()
231
    page3 = Page(title='Three', slug='three', parent=page2, order=2, template_name='standard')
232
    page3.save()
233
    page4 = Page(title='Four', slug='four', parent=page2, order=3, template_name='standard')
234
    page4.save()
235

  
236
    ordered_ids = [x.id for x in Page.get_as_reordered_flat_hierarchy(Page.objects.all())]
237
    ordered_ids = [page1.id, page2.id, page3.id, page4.id]
238

  
239
    # move page4 before page3
240
    app = login(app)
241
    resp = app.get('/manage/pages/order', params={
242
        'moved-page-id': page4.id,
243
        'moved-page-new-parent': page2.id,
244
        'new-order': ','.join([str(x) for x in [page1.id, page2.id, page4.id, page3.id]])})
245

  
246
    ordered_ids = [x.id for x in Page.get_as_reordered_flat_hierarchy(Page.objects.all())]
247
    ordered_ids = [page1.id, page2.id, page4.id, page3.id]
248

  
249
    # move page4 to level0
250
    resp = app.get('/manage/pages/order', params={
251
        'moved-page-id': page4.id,
252
        'moved-page-new-parent': '',
253
        'new-order': ','.join([str(x) for x in [page1.id, page4.id, page2.id, page3.id]])})
254
    ordered_ids = [x.id for x in Page.get_as_reordered_flat_hierarchy(Page.objects.all())]
255
    ordered_ids = [page1.id, page4.id, page2.id, page3.id]
256

  
257
    # change slug to check for autochange on duplicate
258
    page4.slug = 'three'
259
    page4.save()
260
    # move it as a sibling of page3
261
    resp = app.get('/manage/pages/order', params={
262
        'moved-page-id': page4.id,
263
        'moved-page-new-parent': page2.id,
264
        'new-order': ','.join([str(x) for x in [page1.id, page2.id, page4.id, page3.id]])})
265
    assert Page.objects.get(id=page4.id).slug.startswith('three-')
266

  
225 267
def test_export_page(app, admin_user):
226 268
    Page.objects.all().delete()
227 269
    page = Page(title='One', slug='one', template_name='standard')
228
-