Django 4 ограничение уникальности IntegrityError - PullRequest
0 голосов
/ 24 сентября 2018

Я создаю приложение для парковки, и моя проблема в том, что я использовал 4 разных ограничения.

Моя проблема: если 25 октября у меня забронирован пункт P1 с 9-17, я хочу, чтобы он был свободен для бронирования с 18-24.

Мои модели:

from django.db import models
from django.conf import settings
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from datetime import datetime, timedelta, time
from django.core.exceptions import NON_FIELD_ERRORS
today = datetime.now().date()
tomorrow = today + timedelta(1)
now = datetime.now()
l = now.hour
m=int(now.strftime("%H"))

class ParcareManager(models.Manager):
    def active(self, *args, **kwargs):
        return super(ParcareManager, self).filter(draft=False).filter(parking_on__lte=datetime.now())


class Parcare(models.Model):
    PARKING_PLOT = (('P1', 'Parking #1'), ('P2', 'Parking #2'),('P3', 'Parking #3'))
    user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True,null=True, default=1, on_delete=True)
    email=models.EmailField(blank=True, null=True)
    parking_on = models.DateField(auto_now=False, auto_now_add=False,blank=True, null=True,
                                  help_text='Alege data cand doresti sa vii in office',)
    parking_off = models.DateField(auto_now=False, auto_now_add=False, blank=True, null=True, 
                                help_text='Alege Data Plecarii')  
    numar_masina = models.CharField(max_length=8, default="IF77WXV",blank=True, null=True, 
                                help_text='Introdu Numarul Masinii')
    location = models.CharField(max_length=3, blank=True, default="P1",null=True, choices=PARKING_PLOT,
                                help_text='Alege Locul de Parcare Dorit')
    updated = models.DateTimeField(auto_now=True, auto_now_add=False,blank=True, null=True)
    timestamp=models.DateTimeField(auto_now=False, auto_now_add=True,blank=True, null=True)
    venire = models.TimeField(default=time(9, 00), auto_now=False,auto_now_add=False, help_text='Alege Ora Venirii')
    plecare = models.TimeField(default=time(18, 00), auto_now=False, auto_now_add=False, help_text='Alege Ora Plecarii')
    objects = ParcareManager()

    def __str__(self):
        return self.location + " | " + str(self.parking_on) + " | " + str(self.parking_off)

    def validate_unique(self, exclude=None):
        try:
            super(Parcare, self).validate_unique()
        except ValidationError as e:
            raise ValidationError("Dear " + str(self.user) + 
            " seems that the parking places "+ str(self.location) + 
            " you want to book, is already taken on "+ str(self.parking_on) + " at"+ str(self.venire)+" !"+
            " Please select another date! ")

    class Meta:
        verbose_name_plural = "parcare"
        ordering = ["-parking_on"]
        unique_together = ("parking_on", "location", "venire", "plecare")

Ошибка:

IntegrityError at /admin/parcare/parcare/add/
UNIQUE constraint failed: parcare_parcare.parking_on, parcare_parcare.location, parcare_parcare.venire, parcare_parcare.plecare

Это работает как брелок, если пользователь выбирает бронирование 25-го числа с 9-17, но дает мне эту ошибку с 18-24.

Администратор:

from django.contrib import admin
from .models import Parcare
from django.core.exceptions import NON_FIELD_ERRORS


class ParcareModelAdmin(admin.ModelAdmin):
    list_display = ["user", "location",
                    "parking_on", "parking_off",  "venire", "plecare", "timestamp"]
    list_display_links = ["user" , "location"]
    list_editable = [ "parking_off", "parking_on","venire", "plecare"]
    list_filter = ["parking_on","location", "email"]
    search_fields = ["location", "parking_on"]
    date_hierarchy='parking_on'

    class Meta: 
        model = Parcare

    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        if not obj:
            user = request.user
            form.base_fields['user'].initial = user
            form.base_fields['email'].initial = user.email
        return form 

admin.site.register(Parcare, ParcareModelAdmin)

работает нормально только с unique_together = ("parking_on", "location"), но мне нужно какое-то подтверждение для часа, когда они хотят приходить и уходить.

1 Ответ

0 голосов
/ 28 сентября 2018
def save(self, *args, **kwargs):
        delta = self.parking_off.date() - self.parking_on.date()
        if delta.days == 0:
            super().save(*args, **kwargs)
        else:
            day = self.parking_on
            booking_days = []
            for i in range(delta.days+1):
                print('day variable is', day.date())
                print('parking_off date is', self.parking_off.date())
                if day.date() == self.parking_on.date():
                    booking_days.append(
                        Parcare(
                            user=self.user,
                            email=self.email,
                            parking_on=self.parking_on,
                            parking_off=self.parking_on.replace(hour=18, minute=0, second=0),
                            location=self.location
                        )
                    )
                    day = day + datetime.timedelta(days=1)
                    continue
                elif day.date() == self.parking_off.date():
                    booking_days.append(
                        Parcare(
                            user=self.user,
                            email=self.email,
                            parking_on=self.parking_off.replace(hour=9, minute=0, second=0),
                            parking_off=self.parking_off,
                            location=self.location
                        )
                    )
                else:
                    booking_days.append(
                        Parcare(
                            user=self.user,
                            email=self.email,
                            parking_on=self.parking_on.replace(hour=9, minute=0, second=0) + datetime.timedelta(days=i),
                            parking_off=self.parking_off.replace(hour=18,
                                                                 minute=0,
                                                                 second=0) - datetime.timedelta(days=delta.days-i),
                            location=self.location
                        )
                    )
                    day = day + datetime.timedelta(days=1)
            Parcare.objects.bulk_create(booking_days)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...