Projet

Général

Profil

« Précédent | Suivant » 

Révision bf5d84a3

Ajouté par Serghei Mihai (congés, retour 15/05) il y a plus de 7 ans

use unique category slugs in urls (#13791)

Voir les différences:

corbo/forms.py
1 1
from django import forms
2 2
from django.utils.translation import ugettext_lazy as _
3 3
from django.utils.text import slugify
4
from django.core.exceptions import ObjectDoesNotExist
4 5

  
5 6
from .models import Announce, Category, Broadcast, channel_choices
6 7

  
......
31 32
        model = Category
32 33

  
33 34
    def save(self, commit=True):
35
        slug = slugify(self.instance.name)
36
        base_slug = slug
34 37
        if not self.instance.slug:
35
            self.instance.slug = slugify(self.instance.name)
38
            i = 1
39
            while True:
40
                try:
41
                    c = Category.objects.get(slug=slug)
42
                except ObjectDoesNotExist:
43
                    break
44
                i += 1
45
                slug = '%s-%s' % (base_slug, i)
46
            self.instance.slug = slug
36 47
        return super(CategoryForm, self).save(commit=commit)
corbo/manage_urls.py
6 6

  
7 7
urlpatterns = patterns('',
8 8
            url(r'^$', manage, name='manage'),
9
            url(r'^category/(?P<pk>\d+)/announce/$', add_announce,
9
            url(r'^category/(?P<slug>[\w-]+)/announce/$', add_announce,
10 10
                name='add_announce'),
11 11
            url(r'^announce/edit/(?P<pk>\d+)$', edit_announce,
12 12
                name='edit_announce'),
13 13
            url(r'^announce/delete/(?P<pk>\d+)$', delete_announce,
14 14
                name='delete_announce'),
15
            url(r'^category/(?P<pk>\d+)/$', view_category,
15
            url(r'^category/(?P<slug>[\w-]+)/$', view_category,
16 16
                name='view_category'),
17 17
            url(r'^category/add$', add_category,
18 18
                name='add_category'),
19
            url(r'^category/edit/(?P<pk>\d+)$', edit_category,
19
            url(r'^category/edit/(?P<slug>[\w-]+)$', edit_category,
20 20
                name='edit_category'),
21
            url(r'^category/delete/(?P<pk>\d+)$', delete_category,
21
            url(r'^category/delete/(?P<slug>[\w-]+)$', delete_category,
22 22
                name='delete_category'),
23 23
            url(r'^menu.json$', menu_json),
24 24
)
corbo/migrations/0009_auto_20170120_1533.py
1
# -*- coding: utf-8 -*-
2
from __future__ import unicode_literals
3

  
4
from django.db import migrations, models
5
from django.utils.text import slugify
6

  
7

  
8
class Migration(migrations.Migration):
9

  
10
    dependencies = [
11
        ('corbo', '0008_category_slug'),
12
    ]
13

  
14
    def make_slug_unique(apps, schema_editor):
15
        Category = apps.get_model('corbo', 'Category')
16
        for category in Category.objects.all():
17
            category.slug = slugify(category.name)
18
            category.save()
19

  
20
    operations = [
21
        migrations.RunPython(make_slug_unique),
22
        migrations.AlterField(
23
            model_name='category',
24
            name='slug',
25
            field=models.SlugField(unique=True, verbose_name='Slug'),
26
        ),
27
    ]
corbo/models.py
43 43

  
44 44
class Category(models.Model):
45 45
    name = models.CharField(_('Name'), max_length=64, blank=False, null=False)
46
    slug = models.SlugField(_('Slug'))
46
    slug = models.SlugField(_('Slug'), unique=True)
47 47
    rss_feed_url = models.URLField(_('Feed URL'), blank=True, null=True,
48 48
                help_text=_('if defined, announces will be automatically created from rss items'))
49 49
    ctime = models.DateTimeField(auto_now_add=True)
corbo/templates/corbo/announce_form.html
4 4
{% block breadcrumb %}
5 5
{{ block.super }}
6 6
{% if category %}
7
<a href='{% url "view_category" pk=category.pk %}'>{{ category }}</a>
7
<a href='{% url "view_category" slug=category.slug %}'>{{ category }}</a>
8 8
{% endif %}
9 9
{% endblock %}
10 10

  
......
26 26
  {{ form.as_p }}
27 27
  <div class="buttons">
28 28
    <button>{% trans "Save" %}</button>
29
    <a class="cancel" href="{% url 'view_category' pk=category.pk %}">{% trans 'Cancel' %}</a>
29
    <a class="cancel" href="{% url 'view_category' slug=category.slug %}">{% trans 'Cancel' %}</a>
30 30
  </div>
31 31
  <script type="text/javascript">
32 32
    $(function() {
corbo/templates/corbo/category_detail.html
4 4
{% block breadcrumb %}
5 5
{{ block.super }}
6 6
{% if category %}
7
<a href='{% url "view_category" pk=category.pk %}'>{{ category }}</a>
7
<a href='{% url "view_category" slug=category.slug %}'>{{ category }}</a>
8 8
{% endif %}
9 9
{% endblock %}
10 10

  
11 11
{% block appbar %}
12 12
<h2>{{ object.name }}</h2>
13
<a href="{% url 'delete_category' object.id %}" rel="popup">{% trans 'Delete' %}</a>
14
<a href="{% url 'edit_category' object.id %}" rel="popup">{% trans 'Edit' %}</a>
15
<a href="{% url 'add_announce' pk=object.pk %}">{% trans 'New announce' %}</a>
13
<a href="{% url 'delete_category' slug=object.slug %}" rel="popup">{% trans 'Delete' %}</a>
14
<a href="{% url 'edit_category' slug=object.slug %}" rel="popup">{% trans 'Edit' %}</a>
15
<a href="{% url 'add_announce' slug=object.slug %}">{% trans 'New announce' %}</a>
16 16
{% endblock %}
17 17

  
18 18
{% block content %}
corbo/templates/corbo/manage.html
11 11
  <ul class='objects-list single-links'>
12 12
    {% for obj in object_list %}
13 13
    <li class='category'>
14
        <a href="{% url 'view_category' pk=obj.id %}">{{ obj.name }} /
14
        <a href="{% url 'view_category' slug=obj.slug %}">{{ obj.name }} /
15 15
          {% blocktrans count announces_number=obj.get_announces_count %}
16 16
          {{ announces_number }} announce
17 17
          {% plural %}
corbo/views.py
58 58
    template_name = 'corbo/announce_form.html'
59 59

  
60 60
    def get_success_url(self):
61
        return reverse('view_category', kwargs={'pk': self.object.category.pk})
61
        return reverse('view_category', kwargs={'slug': self.object.category.slug})
62 62

  
63 63
    def get_initial(self):
64 64
        initial = super(AnnounceCreateView, self).get_initial()
65
        initial['category'] = models.Category.objects.get(pk=self.kwargs['pk'])
65
        initial['category'] = models.Category.objects.get(slug=self.kwargs['slug'])
66 66
        return initial
67 67

  
68 68
    def get_context_data(self, **kwargs):
......
95 95
    model = models.Announce
96 96

  
97 97
    def get_success_url(self):
98
        return reverse('view_category', kwargs={'pk': self.object.category.pk})
98
        return reverse('view_category', kwargs={'slug': self.object.category.slug})
99 99

  
100 100

  
101 101
delete_announce = AnnounceDeleteView.as_view()
......
121 121
    model = models.Category
122 122

  
123 123
    def get_success_url(self):
124
        return reverse('view_category', kwargs={'pk': self.object.pk})
124
        return reverse('view_category', kwargs={'slug': self.object.slug})
125 125

  
126 126

  
127 127
edit_category = CategoryEditView.as_view()
tests/test_emailing.py
9 9
from django.core import mail, signing
10 10
from django.utils import timezone
11 11
from django.core.files.storage import DefaultStorage
12
from django.utils.text import slugify
12 13

  
13 14
from corbo.models import Category, Announce, Subscription, Broadcast, transform_image_src
14 15

  
15 16
pytestmark = pytest.mark.django_db
16 17

  
17
CATEGORIES = ('Alerts', 'News')
18
CATEGORIES = (u'Alerts', u'News')
18 19

  
19 20

  
20 21
@pytest.fixture
21 22
def categories():
22 23
    categories = []
23 24
    for category in CATEGORIES:
24
        c, created = Category.objects.get_or_create(name=category)
25
        c, created = Category.objects.get_or_create(name=category, slug=slugify(category))
25 26
        categories.append(c)
26 27
    return categories
27 28

  

Formats disponibles : Unified diff