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.
3 respuestas
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)
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:
- 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
- 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)
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
Preguntas relacionadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.