2017-10-15 5 views
0

Je construis un CMS de base. J'ai créé une application d'organisation, qui ajoute un ID de projet avec une clé étrangère à tous mes objets de modèle. Le formulaire sert à créer un objet de site Web de base avec en-tête et texte. J'ai été capable de créer et enregistrer une instance avec le code suivant. "1062," Dupliquer l'entrée "pour la clé 'cms_page_url_117a950602ffab5c_uniq'")Django avec unique_together sur clé étrangère et slug = slugify échoue

Je sais maintenant où je vais mal, quelqu'un peut-il me diriger dans la bonne direction? . base de données MySQL

Modèle:

class Page(models.Model): 
    title = models.CharField(max_length=100) 
    text = models.TextField(blank=True) 

    slug = models.SlugField() 

    date_created = models.DateTimeField(auto_now_add=True) 
    last_modified = models.DateTimeField(default=timezone.now) 

    project = models.ForeignKey(Project) 

    def __unicode__(self): 
     return "Page '%s' @: %s from %s" % (self.title, self.slug, self.project) 

    def __str__(self): 
     return unicode(self).encode('utf-8') 

    def save(self, *args, **kwargs): 
     self.slug = slugify(self.title) 
     super(Page, self).save(*args, **kwargs) 

    class Meta: 
     unique_together = (("project", "slug"),) 

Forme:

class PageForm(ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(PageForm, self).__init__(*args, **kwargs) 
     for key, field in six.iteritems(self.fields): 
      field.widget.attrs['placeholder'] = field.label 

    class Meta: 
     model = Page 
     fields = ['title', 'text'] 
     # TODO: ordering 

    title = forms.CharField(max_length=100, label=ugettext_lazy("Add a title")) 
    text = forms.CharField(label=ugettext_lazy("Type your text here"), widget=forms.Textarea) 

    def save(self, project, commit=True): 
     instance = super(PageForm, self).save(commit=False) 
     instance.project = project 

     if commit: 
      instance.save() 

     return instance 

Voir (CreateView):

class PagesCreateView(CreateView): 
    success_url = reverse_lazy('guiWeb') 
    form_class = PageForm 
    template_name = 'cms/page_create.html' 

    def form_valid(self, form): 
     project = Project.objects.get(id=self.request.session['authority']) 

    #Handle IntegrityError in view to avoid race condition. 
    try: 
     self.object = form.save(project=project) 
    except IntegrityError: 
     form.add_error('title', 'Page titles must be unique') 
     return self.form_invalid(form) 

    return HttpResponseRedirect(self.get_success_url()) 

Voici la dernière déclaration d'erreur:

/usr/local/lib/python2.7/dist-packages/MySQL_python-1.2.4b4-py2.7-linux-x86_64.egg/MySQLdb/cursors.py in execute 

          self.errorhandler(self, exc, value) 

    ... 

▼ Local vars 
Variable Value 
args  

[u'This is a new page 2', 
u'dffjghk', 
u'this-is-a-new-page-2', 
u'2017-10-15 15:37:18', 
u'2017-10-15 15:37:18', 
4] 

exc  

<class '_mysql_exceptions.IntegrityError'> 

self  

<MySQLdb.cursors.Cursor object at 0x7faa0dbbbb10> 

charset  

'utf8' 

db 

<weakproxy at 0x7faa0db87aa0 to Connection at 0x7faa0844c330> 

value 

IntegrityError(1062, "Duplicate entry '' for key 'cms_page_url_117a950602ffab5c_uniq'") 

r 

None 

query 

"INSERT INTO `cms_page` (`title`, `text`, `slug`, `date_created`, `last_modified`, `project_id`) VALUES ('This is a new page 2', 'dffjghk', 'this-is-a-new-page-2', '2017-10-15 15:37:18', '2017-10-15 15:37:18', 4)" 

Répondre

0

Ok, j'ai eu une migration incomplète dans le système ... Il aurait dû être clair pour moi de l'information « cms_page_url ». Dans la version précédente du modèle, j'avais un champ uniq appelé url dans mon modèle, que j'ai supprimé. Comme la migration était incomplète, elle était toujours dans la base de données et renvoyait les erreurs. (IntegrityErrors proviennent de la base de données sous-jacente et non de django).

J'espère que mon raisonnement et le code ci-dessus peuvent toujours être utiles à quelqu'un dans le futur.