Wednesday, May 30, 2012

Re: Foreign Key Chicken/Egg Inline Fu

I just checked on my own code that does something in a different
context but kinda performs the same check. I thought I'd share it with
you in case it helps out at all.

def clean_title(self):

# Grab the data to verify this Title is unique to this user.
title = self.cleaned_data['title']
owner = self.request.user
slug = slugify(title)

# Grab all user pages query for validation
user_pages = AbstractPage.objects.filter(owner = owner)
user_pages = user_pages.exclude(pk = self.instance.pk)

# Validate Uniqueness
if user_pages.filter(title = title).exists():
raise ValidationError("The page title must be unique. It appears "
+ "you already have a page with this title.")
elif user_pages.filter(slug = slug).exists():
raise ValidationError("It appears that you're trying to use two "
+ " pages with titles that are too similar.")
else: return title

Of course, you'd want to 'clean' the Captain boolean field and make
sure that no other player in the same team is a captain before
allowing it to pass. Different context, but hopefully this approach
can help.

On Wed, May 30, 2012 at 4:05 PM, Kurtis Mullins
<kurtis.mullins@gmail.com> wrote:
> Sorry, I completely mis-read the last part of your problem. You
> already thought about the same solution, haha. You might be able to
> modify the Player model's clean (or save) method to prohibit any Team
> from having more than one team captain. However, I'd probably just
> check it in the Form you're using (outside of Admin)
>
> On Wed, May 30, 2012 at 4:02 PM, Kurtis Mullins
> <kurtis.mullins@gmail.com> wrote:
>> Unless a player can play for multiple teams (which I'm doubting since
>> Team is a ForeignKey for a Player), why not remove that 'captain'
>> attribute from your Team and put it into your Player model as a
>> boolean field? You could create a ModelManager or class-level model
>> method to grab the associated team caption if you want to access it
>> easily. Otherwise, it's just a matter of:
>>
>> Team.objects.get('team_name').player_set.filter(captain=True) # Or
>> something along those lines...
>>
>> Just an idea anyways :) Good luck!
>>
>> On Wed, May 30, 2012 at 2:15 PM, Patrick Gavin <wezelboy@gmail.com> wrote:
>>> Hi-
>>>
>>> I'm new to Django, but so far I think it is the bee's knees.
>>>
>>> I could use some insight into a problem I'm working on.
>>>
>>> Given the following...
>>>
>>> ---------------------------------
>>> # models.py
>>>
>>> from django.db import models
>>>
>>> class Team(models.Model):
>>>    name = models.CharField(max_length=30)
>>>
>>>    # captain is a player- but there can only be one captain per team.
>>>    # null and blank are true to allow the team to be saved despite
>>> not having a captain
>>>    captain = models.ForeignKey('Player', related_name='team_captain',
>>> null=True, blank=True)
>>>
>>>    def __unicode__(self):
>>>        return u'{0}'.format(self.name)
>>>
>>> class Player(models.Model):
>>>    first_name = models.CharField(max_length=20)
>>>    last_name = models.CharField(max_length=30)
>>>    team = models.ForeignKey('Team')
>>>
>>>    def __unicode__(self):
>>>        return u'{0} {1}'.format(self.first_name, self.last_name)
>>>
>>>
>>> # admin.py
>>>
>>> from league.models import *
>>> from django.contrib import admin
>>>
>>> class PlayerInline(admin.TabularInline):
>>>    model = Player
>>>    extra = 8
>>>
>>> class TeamAdmin(admin.ModelAdmin):
>>>    inlines = [PlayerInline]
>>>    list_display = ('name', 'captain')
>>>
>>> ---------------------------------
>>>
>>> As is, when I create a new team in the admin interface I can add the
>>> players inline, but I have to leave the team captain blank, save the
>>> team, and then go back and change the team and set the captain to one
>>> of the players added previously. This is kind of a drag though.
>>>
>>> Is there a way that I can make the team captain be automatically set
>>> to the first player entered inline when the team is saved the first
>>> time?
>>>
>>> I 've thought about adding a boolean field to the Player model called
>>> "is_captain", but I want to enforce only one captain per team. If I
>>> were to go this route, is there a way I could make the is_captain
>>> field default to True for the first inline entry but false for the
>>> rest?
>>>
>>> Thanks,
>>>
>>> -Patrick
>>>
>>> --
>>> 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 django-users+unsubscribe@googlegroups.com.
>>> For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
>>>

--
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 django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

No comments:

Post a Comment