Django, Postgres DateRangeField

时间:2018-04-18 17:57:30

标签: python django postgresql django-models

im using the range fields feature for postgrest in Django, and i made a model in wich the date from and date to are stored in a range for checking if it overlaps, but there is a problem, if the date from and date to are the same date the model get stored like this.

DateRange(empty=True)

I tested that this DateRange feature can store a range that has the same date at start and at the end if i test it in the shell, but, in the model when it gets saved it just save it like i just mentioned before.

¿What can i do?

Edit:

This is the code.

class Reservaciones(models.Model):
    class Meta:
        verbose_name_plural = "Reservaciones"

    def random_string():
        return str(
            randint(10000, 999999999)
        )

    fechas_semana = [
        timezone.localdate() + timedelta(days=i)
        for i in range (
            0 - date.today().weekday(),
            7 - date.today().weekday()
        )
    ]
    fecha_vie = fechas_semana[4]

    ESTADOS= (
        ("Pendiente", "Pendiente"),
        ("Reservado", "Reservado"),
        ("Usado", "Usado"),
    )
    nucleo = models.ForeignKey(
        Nucleo,
        on_delete = models.CASCADE,
        null = False,
        blank = False,
        limit_choices_to = {
            'estado': "Activo"
        }        
    )
    cabaña = models.ForeignKey(
        Cabaña,
        on_delete = models.CASCADE,
        null = False,
        blank = False,
        limit_choices_to = {
            'estado': "Activo"
        }
    )
    estado = models.CharField(
        max_length = 10,
        choices = ESTADOS,
        default = "Pendiente",
        null = False,
        blank = False
    )
    fecha_desde = models.DateField(
        null = True,        
        blank = True,
    )       
    fecha_hasta = models.DateField(
        null = True,        
        blank = True,
    )       
    fechas = DateRangeField(
    )   
    fecha_exp = models.DateField(
        null = False,        
        blank = False,
    )    
    usuario = models.ForeignKey(
        get_user_model(),
        on_delete = models.CASCADE,
        null = False,
        blank = False
    )
    codigo = models.CharField(
        max_length = 10,
        editable = False,
        unique = True,
        default = random_string,        
        null = False,
        blank = False
    )
    envio = models.DateTimeField(
        auto_now = False,
        auto_now_add = True
    )
    envio_dia = models.DateField(
        auto_now = False,
        auto_now_add = True
    )    
    actualizado = models.DateTimeField(
        auto_now = True,
        auto_now_add = False
    )    
    observacion = models.TextField(
        null = True,        
        blank = True
    )
    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)

    def __str__(self):
        return "%s" % self.codigo

    def save(self, *args, **kwargs):
        self.fechas = DateRange(self.fecha_desde, self.fecha_hasta)
        super(Reservaciones, self).save(*args, **kwargs)

    def clean(self):

        if Reservaciones.objects.filter(fechas__overlap=DateRange(self.fecha_desde - timedelta(days=1), self.fecha_hasta + timedelta(days=1))
        ).filter(
            nucleo = self.nucleo
        ).filter(
            cabaña=self.cabaña
        ).exclude(
            codigo = self.codigo
        ).difference(
            Reservaciones.objects.filter(estado="Pendiente", fecha_exp__lt=timezone.localdate())
        ).exists():
            raise ValidationError("Ya existe una reservación para esta cabaña en las fechas que haz seleccionado.")  
        elif self.fecha_desde == self.fecha_hasta and Reservaciones.objects.filter(
            fecha_desde=self.fecha_desde
        ).filter(
            fecha_hasta=self.fecha_hasta
        ).filter(
            nucleo = self.nucleo
        ).filter(
            cabaña=self.cabaña
        ).exclude(
            codigo = self.codigo
        ).difference(
            Reservaciones.objects.filter(estado="Pendiente", fecha_exp__lt=timezone.localdate())
        ).exists():
            raise ValidationError("Ya existe una reservación para esta cabaña en las fechas que haz seleccionado.")  
        elif self.fecha_hasta < self.fecha_desde:  
            raise ValidationError("La fecha maxima de la reservación no puede ser inferior a la fecha de inicio de la misma.") 
        elif self.cabaña_id not in list(Cabaña.objects.filter(nucleo=self.nucleo, id=self.cabaña_id).values_list('id', flat=True)):         
            raise ValidationError("Esta cabaña no existe en este nucleo.") 

This work just perfect to validate the dates.

But for this bussines logic, i just let the users choose from the form the dates and room (Cabaña) that are not occupied

def ReservacionCargarCabañaView(request):
    nucleo = request.GET.get('nucleo')
    fecha_desde = request.GET.get('fecha_desde')
    fecha_hasta = request.GET.get('fecha_hasta')    
    fecha_desde = datetime.strptime(fecha_desde, '%Y-%m-%d') - timedelta(days=1)   
    fecha_hasta = datetime.strptime(fecha_hasta, '%Y-%m-%d') + timedelta(days=1)  
    fecha_desde = date(fecha_desde.year, fecha_desde.month, fecha_desde.day)
    fecha_hasta = date(fecha_hasta.year, fecha_hasta.month, fecha_hasta.day)    

    cabaña = Cabaña.objects.filter(
        nucleo=nucleo
    ).exclude(
        estado="Inactivo"
    ).exclude(
        id__in=Reservaciones.objects.filter(fechas__overlap=DateRange(fecha_desde, fecha_hasta)
        ).exclude(
            id__in=Reservaciones.objects.filter(estado="Pendiente", fecha_exp__lt=timezone.localdate()).values_list('id')
        ).values_list(
        'cabaña'
        )
    ).order_by(
        'cabaña'
    ) 

    return render(
        request,
        'socios/formulario/cabaña_opciones_lista.html',
        {
            'cabaña': cabaña,
        }
    )

enter image description here

But if for example i choose in fecha desde and fecha hasta the same date to make a reservation for a single date, the form does not hide the rooms (Cabañas).

enter image description here

The form ajax list does not hide the "Cabaña 1" because that reservation made for date 18/4/2018 has a DateRange empty has i stated before.

0 个答案:

没有答案