postgresql 我如何可以过滤与foregin键

xbp102n0  于 2023-10-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(110)

0
我有一个足球场预订网站--用户登录,然后选择他想预订的体育场,然后选择日期和他想预订多少罐装(一个小时或两个小时,等等。用户John在5日10点到12点预订了体育场X,我想确保在同一体育场、同一天和同一时间没有预订,如果在同一数据有预订,他没有完成预订
当我尝试使用外键过滤模型时,pitche filter = OpeningHours.objects.filter(made_on=self.made_on,pitche=self.pitche,period = self.period).filter(Q(from_hour__range=in_range))|Q(to_hour__range=in_range)).exists()
发生错误(relatedobjectdoesnotexist)OpeningHours没有间距。
我的模特是:

  1. class Pitche(models.Model):
  2. Name = models.CharField(max_length=50)
  3. city =models.CharField(max_length=50)
  4. photo = models.ImageField(upload_to='photos')
  5. price = models.DecimalField(max_digits=5,decimal_places=2)
  6. location = models.CharField(max_length=500)
  7. name_of_supervisor = models.CharField(max_length=50)
  8. phone_of_supervisor = models.CharField(max_length=11)
  9. manager = models.ForeignKey(Manager,on_delete=models.DO_NOTHING)
  10. class OpeningHours(models.Model):
  11. user = models.ForeignKey(User,on_delete=models.CASCADE)
  12. pitche = models.ForeignKey(Pitche,on_delete=models.DO_NOTHING)
  13. made_on = models.DateField()
  14. period = models.CharField(max_length=50,choices=period)
  15. from_hour = models.TimeField()
  16. to_hour = models.TimeField()
  17. timing = models.CharField(max_length=50,choices=timing)
  18. def __str__(self):
  19. return f"{self.pitche}-{self.from_hour} to {self.to_hour}"
  20. def clean(self):
  21. if self.from_hour == self.to_hour:
  22. raise ValidationError("Wrong Time")
  23. if self.made_on <datetime.date.today():
  24. raise ValidationError("InVaild Date")
  25. #####################
  26. in_range = (self.from_hour, self.to_hour)
  27. filter = OpeningHours.objects.filter(made_on=self.made_on,period =
  28. self.period).filter(Q(from_hour__range=in_range) |
  29. Q(to_hour__range=in_range)).exists()
  30. if filter:
  31. raise ValidationError(f"The booked time ({self.from_hour} to
  32. {self.to_hour}) is occupied.")
  33. return super().clean()

和意见:

  1. def pitche_page(request,id):
  2. if request.method == 'POST' and request.user.is_authenticated :
  3. pit_id = Pitche.objects.get(id =id )
  4. add_date = RestaurantForm(request.POST)
  5. if add_date.is_valid():
  6. info =add_date.save(commit=False)
  7. login_user = User.objects.get(username=request.user.username)
  8. info.user = login_user
  9. info.pitche = pit_id
  10. info.save()
  11. messages.success(request,"Booking Successful")
  12. else:
  13. messages.error(request,"this time is booked befor")
  14. context ={
  15. 'pit':get_object_or_404(Pitche,id=id),
  16. 'form':RestaurantForm(),
  17. }
  18. return render(request,'pitches/pitche.html',context)
jecbmhm3

jecbmhm31#

问题是,在清理时,pitche尚未设置(尚未),我们可以通过以下方式解决此问题:

  1. def pitche_page(request, id):
  2. if request.method == 'POST' and request.user.is_authenticated:
  3. instance = OpeningHours(pitche_id=id, user=request.user)
  4. add_date = RestaurantForm(request.POST, request.FILES, instance=instance)
  5. if add_date.is_valid():
  6. add_date.save()
  7. messages.success(request, "Booking Successful")
  8. else:
  9. messages.error(request, 'this time is booked before')
  10. else:
  11. form = RestaurantForm()
  12. context = {
  13. 'pit': get_object_or_404(Pitche, id=id),
  14. 'form': form,
  15. }
  16. return render(request, 'pitches/pitche.html', context)

但这种清洁方法可能并不稳健。事实上,假设您想预订下午3:00到下午4:00的场地,并且有一个从下午2:00到下午5:00的预订,那么没有开始和结束日期在下午3:00到下午4:00的范围内,但是它被预订了。
为了解决这个问题,我们应该问自己,当两个范围不 * 总。也就是说,如果 e1<b2e2<b1,其中 biej 分别是开始和结束时间,因此这意味着如果 e1≥b2则e2≥b1。请注意,这并不考虑展期,因此从晚上11:00开始到凌晨1:00结束的预订,这使得它更加复杂。
对于简单的情况,在没有翻转的情况下,我们用以下方式检查:

  1. def clean(self):
  2. if self.from_hour == self.to_hour:
  3. raise ValidationError('Wrong Time')
  4. if self.made_on < datetime.date.today():
  5. raise ValidationError('InVaild Date')
  6. if (
  7. OpeningHours.objects.exclude(pk=self.pk)
  8. .filter(
  9. made_on=self.made_on,
  10. period=self.period,
  11. pitche_id=self.pitche_id,
  12. to_hour__gte=self.from_hour,
  13. from_hour__lte=self.to_hour,
  14. )
  15. .exists()
  16. ):
  17. raise ValidationError(
  18. f'The booked time ({self.from_hour} to {self.to_hour}) is occupied.'
  19. )
  20. return super().clean()

这个时期也很奇怪:这由TimeField中的值暗示:如果选择15:00,时间是15:00,这里用一个period,意思是说如果有人用period='PM'5:007:00之间的话,另外一个人可以用17:0019:00period='AM'period='PM'订,这样就不会出现“撞车”的情况。

注意:通常使用**settings.AUTH_USER_MODEL[Django-doc]引用用户模型比直接使用User模型[Django-doc]更好。有关更多信息,您可以查看文档的 * 引用User模型 * 部分。
注意:如果POST请求成功,需要创建
redirect[Django-doc]来实现Post/Redirect/Get pattern [wiki]。这样可以避免在用户刷新浏览器时发出相同的POST请求。
注意:虽然大多数表单不处理媒体文件,但最好还是将
request.FILES**[Django-doc]传递给表单,这样,如果您稍后添加额外的媒体字段,所有使用表单的视图都会正确处理文件。

展开查看全部

相关问题