Mi objetivo es limitar la cantidad de modelos creados a 3 y ACTUALIZARlos.

Mi model.py es la siguiente:

class FeatureteImage(models.Model):
    park = models.ForeignKey(Park)
    header = models.CharField(max_length=50, blank=True)
    body = models.TextField(max_length=250, blank=True)
    image = models.ImageField(upload_to='featureteimages')

def get_absolute_url(self):
    return reverse('park-features', kwargs={'pk': self.park.pk,})


def save(self, *args, **kwargs):
    park = Park.objects.get(id=self.park.id)
    if park.featurete >= 3:
        pass
    else:
        park.featurete += 1
        park.save()
    super(FeatureteImage, self).save(*args, **kwargs) 

def delete(self, *args, **kwargs):
    park = Park.objects.get(id=self.park.id)
    if park.featurete > 0:
        park.featurete -= 1
        park.save()
        super(FeatureteImage, self).delete(*args, **kwargs)
    else:
        pass

def get_absolute_url(self):
    park = Park.objects.get(id=self.park.id)
    return reverse('park-features', kwargs={'pk': self.park.pk})

Como puede ver, estoy tratando de limitar la cantidad de parque de Featurete. Entonces solo 3 de ellos. Sobrescribí el guardado personalizado () para que si un parque tiene 3 funciones no puedan agregar más.

Pero esto todavía pasa y aún guarda el nuevo modelo Featurete. Pero sí actualiza el modelo.

Primero probé:

def save(self, *args, **kwargs):
    park = Park.objects.get(id=self.park.id)
    if park.featurete >= 3:
        pass
    else:
        park.featurete += 1
        park.save()
        super(FeatureteImage, self).save(*args, **kwargs) 

My views.py:

class AddFeaturete(generic.CreateView):
    template_name = 'images/addfeaturete.html'
    model = FeatureteImage
    fields = ['header', 'body', 'image']

    def form_valid(self, form):
        self.venue = get_object_or_404(Park, pk=self.kwargs['pk'])
        form.instance.park = self.park
        return super(AddFeaturete, self).form_valid(form)

class UpdateFeaturete(generic.UpdateView):
    template_name = 'images/updatefeaturete.html'
    model = FeatureteImage
    fields = ['header', 'body', 'image']

    def get_object(self):
        return get_object_or_404(FeatureteImage, pk=self.kwargs['f_pk'])

    def form_valid(self, form):
        return super(UpdateFeaturete, self).form_valid(form)

Pero cuando intenté actualizar el modelo, no guardó los cambios porque el parque ya tenía 3 funciones y simplemente pasa.

¿Cuál crees que es la mejor manera de resolver esto? Agradezco todas tus respuestas.

0
Tony 10 dic. 2015 a las 17:21

3 respuestas

La mejor respuesta
def save(self, *args, **kwargs):
    if self.park.featureteimage_set.exclude(pk=self.pk).count() >= 3:
        raise ValidationError('too much featuretes')
    super(FeatureteImage, self).save(*args, **kwargs) 
1
Alex Polekha 11 dic. 2015 a las 19:08

El problema es que si hace un recuento de referencias, debe actuar solo si se cambió el atributo de estacionamiento de Featurette, no si el objeto se actualizó de alguna otra manera. Puede resolver eso de dos maneras:

  1. Se deshace del recuento de referencias todos juntos y solo usa el poder de su base de datos relacional para ver cuántos objetos hay
  2. Detecta si el atributo de parque se modificó recuperando la versión de la base de datos y comparándola

Creo que la primera versión sería más elegante si no necesita el recuento muy a menudo, ya que guarda toda la lógica de eliminación.

Nota: actualmente su código tiene el problema adicional de que el contador de referencia no solo necesita ser disminuido al eliminarlo, sino también cuando una actualización cambia el parque. No sé si eso podría ser un problema en su caso de uso.

El método save () con la primera solución se vería así y podría deshacerse de la lógica de eliminación:

def save(self, *args, **kwargs):
    count = self.objects.filter(park=self.park).exclude(pk=self.pk).count()
    if not count < 3:
        raise ValidationError('A park may not contain more than 3 featuretes')
    super(FeatureteImage, self).save(*args, **kwargs) 
0
NEOatNHNG 11 dic. 2015 a las 17:11

Su código pasará si la condición y luego llamará super del modelo que es el comportamiento normal de la función de guardar. Simplemente diga:

def save(self, *args, **kwargs):
    park = Park.objects.get(id=self.park.id)
    if self.pk: #update if it exists
        super(FeatureteImage, self).save(*args, **kwargs) 
    elif park.featurete < 3:
        park.featurete += 1
        park.save()
        super(FeatureteImage, self).save(*args, **kwargs) 
    else:
        return
0
Vahid Msm 11 dic. 2015 a las 16:53
34204265