使用DateField()创建唯一的对象

时间:2019-01-09 13:51:51

标签: django django-models django-forms

我只想创建一个模型,该模型实质上可以防止两个不同的用户(或同一用户)选择相同的日期。
例如,如果User1已选择2019-01-10作为预订的"date",则User2(或任何其他用户)将无法创建同一日期的对象。

我创建了一个非常基本的模型,该模型可以允许不同的用户使用DateField()创建对象。使用Django管理页面,我可以由两个不同的用户(admin和Test_User)创建对象的不同实例。

为了尝试确保如果另一个对象已经使用了该日期,则无法创建新对象,我尝试了以下方法: 利用__dict__的比较功能。

models.py

from __future__ import unicode_literals

from django.db import models, IntegrityError
from django.db.models import Q
from django.contrib.auth.models import User
from datetime import datetime

class Booking(models.Model):
    date = models.DateField(null=False, blank=False)
    booked_at = models.DateTimeField(auto_now_add=True)
    booking_last_modified = models.DateTimeField(auto_now=True)


class PersonalBooking(Booking):
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def compare(self, obj):
        excluded_keys = 'booked_at', '_state', 'booking_last_modified', 'user', 
        return self._compare(self, obj, excluded_keys)

    def _compare(self, obj1, obj2, excluded_keys):
        d1, d2 = obj1.__dict__, obj2.__dict__
        for k,v in d1.items():
            if k in excluded_keys:
                continue
            try:
                if v != d2[k]:
                    pass
            except IntegrityError as error:
                print(error)             
                print('Date already selected by different User. Please select another date.')

admin.py

from django.contrib import admin
from . import models
from .models import Booking, PersonalBooking


class PersonalBookingAdmin(admin.ModelAdmin):
    list_display = ('format_date', 'user', )

    def format_date(self, obj):
        return obj.date.strftime('%d-%b-%Y')

    format_date.admin_order_field = 'date'
    format_date.short_description = 'Date'

    def user(self, obj):
        return obj.user()

    user.admin_order_field = 'user'
    user.short_description = 'User'


admin.site.register(models.PersonalBooking, PersonalBookingAdmin)

它没有我希望的那样工作,具有相同日期的对象仍然可以由相同或不同的用户创建。也许有一个更简单的方法?还是我需要使用Q()类?我不是很熟悉。 任何帮助是极大的赞赏。 谢谢。

2 个答案:

答案 0 :(得分:0)

尝试一下
https://docs.djangoproject.com/en/2.1/ref/models/fields/#unique-for-date 对于user列设置unique_for_date=True

答案 1 :(得分:0)

您可以通过在模型字段中将unique属性设置为True来在数据库级别进行验证。

class Booking(models.Model):
    date = models.DateField(null=False, blank=False, unique=True)
    booked_at = models.DateTimeField(auto_now_add=True)
    booking_last_modified = models.DateTimeField(auto_now=True)

但是如果稍后更改字段以存储时间,则会出现问题。

如果您还要存储时间,则可以覆盖模型的默认save函数,以检查是否没有其他Booking具有相同的date({ {1}})每次保存。如果存在匹配项,exists()返回__date,因此如果存在匹配项,则会抛出True

ValidationError