在将某些记录保存到数据库中时,我需要一些帮助。为停车应用程序工作,我想通过额外的参数来扩展unique_together查询数据库的方式。只是为了了解我的情况。
例如,我为用户提供了在9日至18日(parking_on)位置P1上预订地块的可能性。因为这两个过滤器对于数据库都是唯一的,所以其他人不能在同一日期25日预订相同的图P1,但是从19-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)
class Meta:
verbose_name_plural = "parcare"
ordering = ["-parking_on"]
unique_together = ("parking_on", "location")
def clean(self):
if self.parking_on == today: # merge--vedem dak parcam azi
raise ValidationError(
{'parking_on': _('Please book for a date starting tomorrow')})
if self.parking_off < self.parking_on: # merge-vedem daca bookam in trecut
raise ValidationError(
{'parking_off': _('You cant book for a past date!')})
def save(self):
list = []
d = self.parking_on
while d <= self.parking_off:
list.append(
Parcare(user=self.user,
email=self.email,
parking_on=d,
parking_off=d,
location=self.location
)
)
d = d + timedelta(days=1)
Parcare.objects.bulk_create(list)
from django.contrib import admin
from .models import Parcare
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)
提前谢谢!
答案 0 :(得分:0)
我只是对这个问题有一些想法。
我认为最好的解决方案是替换DateField
上的DateTimeField
。然后,您可以在clean
方法中使用类似以下内容的方法(就像一个性能较差的示例一样):
def clean(self):
qs = Parcare.objects.filter(location=self.location)
.filter(parking_on__gt=self.parking_on)
.filter(parking_off__lt=self.parking_on)
qs2 = Parcare.objects.filter(location=self.location)
.filter(parking_on__gt=self.parking_off)
.filter(parking_off__lt=self.parking_off)
if len(qs) > 0 or len(qs2) > 0:
raise ValidationError('Time is booked already')
if self.parking_on < datetime.now(): # merge--vedem dak parcam azi
raise ValidationError(
{'parking_on': _('Please book for a time more than now')})
if self.parking_off < self.parking_on: # merge-vedem daca bookam in trecut
raise ValidationError(
{'parking_off': _('You cant book for a past date!')})