Repository: zestedesavoir/zds-site

Issue:
Éditer un big-tuto donne une 500
URL : /tutoriels/editer/tutoriel/?tutoriel=3

```
Traceback:
File "lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  112.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/zds/member/decorator.py" in _can_write_and_read_now
  20.         return func(request, *args, **kwargs)
File "lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "/zds/tutorial/views.py" in edit_tutorial
  991.             tutorial.update_children()
File "/zds/tutorial/models.py" in update_children
  352.         chapter = self.get_chapter()
File "/zds/tutorial/models.py" in get_chapter
  147.         return Chapter.objects.get(tutorial__pk=self.pk)
File "lib/python2.7/site-packages/django/db/models/manager.py" in get
  151.         return self.get_queryset().get(*args, **kwargs)
File "lib/python2.7/site-packages/django/db/models/query.py" in get
  310.                 self.model._meta.object_name)

Exception Type: DoesNotExist at /tutoriels/editer/tutoriel/
Exception Value: Chapter matching query does not exist.
```



Discussion:
Encore ? Il semblait que le redémarrage de gnuicorne avait résolut les erreurs 500 il y a quelques minutes.

(cf https://github.com/zestedesavoir/zds-site/issues/1067 )

J'ai cette erreur en local, sur le tag v1.0-RC1.

L'erreur se trouve ici : 

```
def get_chapter(self):
    """Gets the chapter associated with the tutorial if it's small."""
    # We can use get since we know there'll only be one chapter
    return Chapter.objects.get(tutorial__pk=self.pk)
```

D'ailleurs cette fonction est mal commentée puisqu'elle est aussi appelée lors de l'édition d'un big-tuto.

Un workaround serait ceci  : 

```
def get_chapter(self):
    """Gets the chapter associated with the tutorial if it's small."""
    # We can use get since we know there'll only be one chapter
    try:
        return Chapter.objects.get(tutorial__pk=self.pk)
    except Chapter.DoesNotExist:
        return None
```

qui marche chez moi™

Bah alors qu'est ce t'attends ? Elle est ou la PR et son TU ? :D


Resolving patch:
diff --git a/zds/tutorial/models.py b/zds/tutorial/models.py
--- a/zds/tutorial/models.py
+++ b/zds/tutorial/models.py
@@ -144,7 +144,10 @@ def get_parts(self):
     def get_chapter(self):
         """Gets the chapter associated with the tutorial if it's small."""
         # We can use get since we know there'll only be one chapter
-        return Chapter.objects.get(tutorial__pk=self.pk)
+        try:
+            return Chapter.objects.get(tutorial__pk=self.pk)
+        except Chapter.DoesNotExist:
+            return None
 
     def in_beta(self):
         return (self.sha_beta is not None) and (self.sha_beta.strip() != '')
@@ -303,7 +306,7 @@ def last_read_note(self):
                 .latest('note__pubdate').note
         except Note.DoesNotExist:
             return self.first_post()
-    
+
     def first_unread_note(self):
         """Return the first note the user has unread."""
         try:
@@ -344,11 +347,11 @@ def antispam(self, user=None):
             if t.total_seconds() < settings.SPAM_LIMIT_SECONDS:
                 return True
         return False
-    
+
     def update_children(self):
         for part in self.get_parts():
             part.update_children()
-        
+
         chapter = self.get_chapter()
         if chapter:
             chapter.update_children()
@@ -830,7 +833,7 @@ def get_path(self, relative=False):
         return os.path.join(chapter_path, str(self.pk) + "_" + slugify(self.title)) + '.md'
 
     def get_prod_path(self):
-        
+
         if self.chapter.tutorial:
             data = self.chapter.tutorial.load_json_for_public()
             mandata = tutorial.load_dic(data)


Test patch: