I can't post the full code, it was written for a client and has some
secret sauce that I am not at liberty to share, but I'll try to find
the time to develop a santized example.

In the meantime here is the relevent model part. the thing being
reserved is the server, but it could really be anything.

Model class
class Server(meta.Model):
    ip = meta.IPAddressField()
    port = meta.IntegerField()
    created_at = meta.DateTimeField(auto_now_add=True)
    updated_at = meta.DateTimeField(auto_now=True)
    active = meta.BooleanField(default=False)
    name = meta.CharField(maxlength=200,default='unnamed')
    def get_current_stat(self):
        return self.get_serverstat(select_related=True,limit=1)
    def __repr__(self):
        if self.ip and self.port:
            stat = ""
            try:
                stat =  str(self.get_current_stat())
                if len(stat)>2:
                    return "%s %s" % (self.name,stat)
            except:
                pass
            return "%s:%s" % (self.ip,self.port)
        else:
            return self.name
    class META:
        admin = meta.Admin(
            fields = (
            (None, {
                'fields': ('name','ip', 'port', 'active', 'updated_at')
            }),)
        )

class Reservation(meta.Model):
    server = meta.ForeignKey(Server,edit_inline=meta.TABULAR)
    trainer = meta.CharField(maxlength=200,default="Trainer")
    start = meta.DateTimeField(core=True)
    end = meta.DateTimeField()
    def get_absolute_url(self):
        return '''/trainer/obtain_url/%s/''' % self.id
    def __repr__(self):
        if self.trainer and self.start:
            return "%s @ %s" % (self.trainer,
(datetime.timedelta(0,0,0,0,0,-5) + self.start).strftime("%a, %d %b %Y
%H:%M"))
        elif self.id:
            return "Incomplete Reservation %d" % self.id
        else:
            return "Unsaved and Incomplete Reservation"
    def _module_get_future_reservations():
        return get_list(start__gte=datetime.datetime.now())
    def _pre_save(self):
        '''A server is already reserved if there is another reservation
with a start of end date in the
           same range as the new reservation'''
        from  django.models.regservers import AlreadyReserved,
reservations, servers
        from django.core.meta import Q
        server = servers.get_list(id__exact=self.server_id)[0]
        blockers =  server.get_reservation_list(complex=(
Q(start__range=(self.start,self.end)) |

Q(end__range=(self.start,self.end)) )
                                        )
        blockers = [b for b in blockers if b.trainer <> self.trainer]
        if len(blockers)>0:
            raise AlreadyReserved(blockers)
    class META:
        admin = meta.Admin()
        ordering = ['start']


Here is the first view function that lists all of the available
servers.  This could be more elegent.  I pull in all of the active
servers and then iterate through each one looking for active
reservations. This give me a chance to add in more complex logic that
can't be easily done in SQL.  Also for this application the number of
servers is in the 100's and this way is more then fast enough.

def select_server(request):
    start = datetime.datetime.now()
    end = start + datetime.timedelta(0,0,0,0,0,4)
    server_list = []
    all_server_list = servers.get_list(name__contains='RESERVEABLE',
active__exact=True)
    for server in all_server_list:
        if len(server.get_reservation_list(complex=(
Q(start__range=(start,end)) |Q(end__range=(start,end)))))==0:
                server_list.append(server)
    return render_to_response('regservers/select_server',
{'server_list': server_list})

Here is the function that saves a reservation.  I don't use a
manipulator because the input data is pretty simple. Also the servers
can only be reserved for 1-4 hours,  the code that looks like: if
duration.find('one')>=0 has a reason other then validating that the
duration is between 1-4.

def reserve_server(request,ip,port):
    server = get_object_or_404(servers,ip__exact=ip,port__exact=port)
    error = ""
    if request.POST:
        trainer = request.POST.get("trainer","")
        if len(trainer) < 3:
            error = "Please enter the name of the trainer"
        if not error:
            duration = request.POST.get("duration","one")
            print duration
            if duration.find('one')>=0:
                duration = 1
            elif duration.find('two')>=0:
                duration = 2
            elif duration.find('three')>=0:
                duration = 3
            elif duration.find('four')>=0:
                duration = 4
            else:
                duration = 1
            start = datetime.datetime.now()
            end = datetime.timedelta(0,0,0,0,0,duration) + start
            try:
                new_reservation =
server.add_reservation(trainer=trainer,start=start,end=end)
            except AlreadyReserved, e:
                error = 'Please choose another server, %s' % e
            if not error:
                return HttpResponseRedirect("../obtain_url/%i/" %
new_reservation.id)
    return render_to_response('regservers/reserve_server', {'server':
server,'error':error})


Its really not that complex, for error messaging take a look at how I
raise the AlreadyReserved error, it contains a list of all of the
blocking reservations.  Originally I was using this to list out all of
the reservations that are blocking your request. This give the user a
chance to contact the other users and ask them to cancel thier
reservations.  It can also allow you to cancel other reservations based
on something other priority.

Sorry for the delay on the response, but I hope this helps.

Thanks,
-Aaron


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users
-~----------~----~----~----~------~----~------~--~---

Reply via email to