2009-06-17 14 views
6

2 preguntas:Modelos unique_together constraint + None = ¿falla?

  • ¿Cómo puedo evitar los duplicados de que se crean cuando los padres = Ninguno y el nombre es el mismo?
  • ¿Puedo llamar a un método modelo desde dentro del formulario?

Por favor, vea los detalles a continuación:

models.py

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 

nota: babosa = único, así!

forms.py

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)) > 0: 
       raise forms.ValidationError("name not unique") 
     return name 

detalles

El unique_together contraint funciona perfectamente w/el formulario cuando parent != None. Sin embargo, cuando parent == None (nulo) permite la creación de duplicados.

Para tratar de evitar esto, traté de usar el formulario y definí clean_name para intentar buscar duplicados. Esto funciona cuando crea objetos nuevos, pero no funciona cuando se modifican objetos existentes.

Alguien me había mencionado que debería usar commit = False en el archivo .Forma de ModelForm, pero no pude encontrar la manera de hacerlo/implementarlo. También pensé en usar el has_change de ModelForm para detectar cambios en un modelo y permitirlos, pero has_changed también devuelve verdadero en los objetos recién creados con el formulario. ¡ayuda!

Además, (una pregunta algo diferente) ¿puedo acceder al método de modelo make_slug() desde el formulario? I crea que actualmente mi línea exclude = ('slug',) también está ignorando la restricción 'única' en el campo slug, y en el campo guardar modelos, en su lugar, estoy generando el slug. Me preguntaba si podría hacer esto en el forms.py en su lugar?

+0

Ver http://stackoverflow.com/questions/3488264/django-unique- together-doesnt-work-with-foreignkey-none para un método actualizado para manejar este problema. Requiere Django 1.2. –

Respuesta

-1

No estoy seguro de que esto solucione su problema, pero le sugiero que pruebe su código en el último código de tronco de Django. Conseguirlo con:

svn co http://code.djangoproject.com/svn/django/trunk/ 

Ha habido varias correcciones a unique_together desde el lanzamiento de 1,02, por ejemplo véase ticket 9493.

+0

im ya está ejecutando tronco – lostincode

-1

único conjunto debe ser una tupla de tuplas

unique_together = (("parent", "name"),) 
+0

esto ya no es necesario – lostincode

0

Usted podría tener una forma diferente si se está creando o actualización.

Utilice la instancia kwarg al crear una instancia del formulario.

if slug: 
    instance = MyTest.object.get(slug=slug) 
    form = MyUpdateTestForm(instance=instance) 
else: 
    form = MyTestForm() 

Para la segunda parte, creo que es donde se puede traer a cometer = False, algo así como:

if form.is_valid(): 
    inst = form.save(commit=False) 
    inst.slug = inst.make_slug() 
    inst.save() 
Cuestiones relacionadas