Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6839075
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T23:40:29+00:00 2026-05-26T23:40:29+00:00

I am working on a library system to manage certain items in our office,

  • 0

I am working on a library system to manage certain items in our office, I don’t need a full-blown integrated library system so I decided to hand roll one with Django.

Below is a simplified version of my model:

class ItemObjects(models.Model):

# Static Variables
IN_STATUS        = 'Available'
OUT_STATUS       = 'Checked out'
MISSING          = 'Missing'
STATUS_CHOICES   = (
    (IN_STATUS,  'Available'),
    (OUT_STATUS, 'Checked out'),
    (MISSING,    'Missing'),
)

# Fields
slug             = models.SlugField(unique=True)
date_added       = models.DateField(auto_now_add=True)
last_checkin     = models.DateTimeField(editable=False, null=True)
last_checkout    = models.DateTimeField(editable=False, null=True)
last_activity    = models.DateTimeField(editable=False, null=True)
status           = models.CharField(choices=STATUS_CHOICES, default=IN_STATUS, max_length=25)
who_has          = models.OneToOneField(User, blank=True, null=True)
times_out        = models.PositiveIntegerField(default=0, editable=False)
notes            = models.CharField(blank=True, max_length=500)
history          = models.TextField(blank=True, editable=False)
pending_checkin  = models.BooleanField(default=False)
pending_transfer = models.BooleanField(default=False)

At first I was using a method on ItemObject to process checking out an item to a user and who_has was an EmailField because I couldn’t get a CharfField to populate with the logged in user’s name, but I figured using a OneToOneField is probably closer to the “right” way to do this.. While who_has was an EmailField, the following method worked:

    def check_out_itemobject(self, user):
        user_profile                     = user.get_profile()
        if self.status == 'Available' and self.who_has == '':
            self.status                  = 'Checked out'
            self.who_has                 = user.email
            self.last_checkout           = datetime.datetime.now()
            self.last_activity           = datetime.datetime.now()
            self.times_out               += 1
            if self.history == '':
                self.history             += "%s" % user_profile.full_name
            else:
                self.history             += ", %s" % user_profile.full_name
            if user_profile.history == '':
                user_profile.history     += self.title
            else:
                user_profile.history     += ", %s" % self.title
        else:
            return False # Not sure is this is "right"
        user_profile.save()
        super(ItemObjects, self).save()

Now that I am using a OneToOneField this doesn’t work, so I started looking at using a subclass of ModelForm but none of the cases I saw here on SO seemed to apply for what I am trying to do; my form would be a button, and that’s it. Here are some of the questions I looked at:

Django: saving multiple modelforms simultaneously (complex case)

(Django) (Foreign Key Issues) model.person_id May not be NULL

django update modelform

So was I on the right track with a sort of altered save() method, or would a ModelForm subclass be the way to go?

EDIT/UPDATE: Many thanks to @ChrisPratt!

So I am trying to get Chris Pratt’s suggestion for showing ItemHistory to work, but when I try to render it on a page I get an AttributeError that states “‘User’ object has no attribute ‘timestamp'”. So my question is, why is it complaining about a User object when last_activity is an attribute on the ItemObject object ?

My view:

@login_required
def item_detail(request, slug):
    item      = get_object_or_404(Item, slug=slug)
    i_history = item.last_activity
    user      = request.user

    return render_to_response('items/item_detail.html',
                              { 'item'     : item,
                                'i_history': i_history,
                                'user'     : user })

I do not see why a User object is coming up at this point.

EDIT2: Nevermind, history is clearly a M2M field whose target is User. That’s why!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T23:40:30+00:00Added an answer on May 26, 2026 at 11:40 pm

    Assuming users will log in and check out books to themselves, then what you most likely want is a ForeignKey to User. A book will only have one User at any given time, but presumably Users could check out other items as well. If there is some limit, even if the limit is actually one per user, it would be better to validate this in the model’s clean method. Something like:

    def clean(self):
        if self.who_has and self.who_has.itemobject_set.count() >= LIMIT:
            raise ValidationError('You have already checked out your maximum amount of items.')
    

    Now, you checkout method has a number of issues. First, status should be a defined set of choices, not just random strings.

    class ItemObject(models.Model):
        AVAILABLE = 1
        CHECKED_OUT = 2
        STATUS_CHOICES = (
            (AVAILABLE, 'Available'),
            (CHECKED_OUT, 'Checked Out'),
        )
    
        ...
    
        status = models.PositiveIntegerField(choices=STATUS_CHOICES, default=AVAILABLE)
    

    Then, you can run your checks like:

    if self.status == self.STATUS_AVAILABLE:
        self.status = self.STATUS_CHECKED_OUT
    

    You could use strings and a CharField instead if you like, as well. The key is to decouple the static text from your code, which allows much greater flexibility in your app going forward.

    Next, history needs to be a ManyToManyField. Right now, your “history” is only who last checked the item out or what the last item the user checked out was, and as a result is pretty useless.

    class ItemObject(models.Model):
        ...
        history = models.ManyToManyField(User, through='ItemHistory', related_name='item_history', blank=True)
    
    class ItemHistory(models.Model):
        CHECKED_OUT = 1
        RETURNED = 2
        ACTIVITY_CHOICES = (
            (CHECKED_OUT, 'Checked Out'),
            (RETURNED, 'Returned'),
        )
    
        item = models.ForeignKey(ItemObject)
        user = models.ForeignKey(User)
        activity = models.PostiveIntegerField(choices=ACTIVITY_CHOICES)
        timestamp = models.DateTimeField(auto_now_add=True)
    
        class Meta:
            ordering = ['-timestamp'] # latest first
    

    Which then allows you to get full histories:

    some_item.history.all()
    some_user.item_history.all()
    

    To add a new history, you would do:

    ItemHistory.objects.create(item=some_item, user=some_user, activity=ItemHistory.CHECKED_OUT)
    

    The auto_now_add attribute ensures that the timestamp is automatically set when the relationship is created.

    You could then actually get rid of the last_checkout and last_activity fields entirely and use something like the following:

    class ItemObject(models.Model):
        ...
        def _last_checkout(self):
            try:
                return self.history.filter(activity=ItemHistory.CHECKED_OUT)[0].timestamp
            except IndexError:
                return None
        last_checkout = property(_last_checkout)
    
        def _last_activity(self):
            try:
                return self.history.all()[0].timestamp
            except IndexError:
                return None
        last_activity = property(_last_activity)
    

    And, you can then use them as normal:

        some_item.last_checkout
    

    Finally, your checkout method is not an override of save so it’s not appropriate to call super(ItemObject, self).save(). Just use self.save() instead.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am trying to get a multiple upload library working for my Codeigniter based
I'm trying to get the Boost library working in my C++ projects in Eclipse.
I'm working using scriptaculous library. However I'm facing some issues with inclusion of the
I'm working on a Java library and would like to remove some functions from
I'm working on a piece of library code around IDisposable . The managed path
I'm working on a Python library that interfaces with a web service API. Like
I have been working on a WCF service library where hopefully all the business
The current class library I am working on will have a base class (Field)
I am currently working on a REST library for .net, and I would like
I'm working on a thread library which implement user level threads (i have something

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.