Note that there are some explanatory texts on larger screens.

plurals
  1. POModels unique_together constraint + None = fail?
    primarykey
    data
    text
    <p>2 questions:</p> <ul> <li>How can I stop duplicates from being created when parent=None and name is the same?</li> <li>Can i call a model method from within the form? </li> </ul> <p>Please see full details below:</p> <h1>models.py</h1> <pre><code>class MyTest(models.Model): parent = models.ForeignKey('self', null=True, blank=True, related_name='children') name = models.CharField(max_length=50) slug = models.SlugField(max_length=255, blank=True, unique=True) owner = models.ForeignKey(User, null=True) class Meta: unique_together = ("parent", "name") def save(self, *args, **kwargs): self.slug = self.make_slug() super(MyTest, self).save(*args, **kwargs) def make_slug(self): # some stuff here return generated_slug </code></pre> <p>note: slug = unique as well!</p> <h1>forms.py</h1> <pre><code>class MyTestForm(forms.ModelForm): class Meta: model = MyTest exclude = ('slug',) def clean_name(self): name = self.cleaned_data.get("name") parent = self.cleaned_data.get("parent") if parent is None: # this doesn't work when MODIFYING existing elements! if len(MyTest.objects.filter(name = name, parent = None)) &gt; 0: raise forms.ValidationError("name not unique") return name </code></pre> <h1>Details</h1> <p>The <code>unique_together</code> contraint works perfectly w/ the form when <code>parent != None</code>. However when <code>parent == None</code> (null) it allows duplicates to be created.</p> <p>In order to try and avoid this, i tried using the form and defined clean_name to attempt to check for duplicates. This works when <em>creating</em> new objects, but doesn't work when modifying existing objects.</p> <p>Someone had mentioned i should use commit=False on the ModelForm's .save, but I couldn't figure out how to do/implement this. I also thought about using the ModelForm's has_changed to detect changes to a model and allow them, but has_changed returns true on newly created objects with the form as well. help!</p> <p>Also, (somewhat a completely different question) can I access the make_slug() model method from the Form? I <em>believe</em> that currently my <code>exclude = ('slug',)</code> line is also ignoring the 'unique' constraint on the slug field, and in the models save field, I'm generating the slug instead. I was wondering if i could do this in the forms.py instead?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload