I have this model:
from django.db import models
from django.contrib.auth.models import User
from django.templatetags.static import static
from simple_history.models import HistoricalRecords
from treebeard.mp_tree import MP_Node
from . import constants
from datetime import datetime
class Profile(models. Model):
# Managed fields
user = models.OneToOneField(User, related_name="profile", on_delete=models.CASCADE)
memberId = models.CharField(unique=True, max_length=15, null=False, blank=False, default=GenerateFA)
avatar = models.ImageField(upload_to="static/MCARS/img/members", null=True, blank=True)
birthday = models.DateField(null=True, blank=True)
gender = models.CharField(max_length=10, choices=constants.GENDER_CHOICES, null=True, blank=True)
invited = models.BooleanField(default=False)
registered = models.BooleanField(default=False)
height = models.PositiveSmallIntegerField(null=True, blank=True)
phone = models.CharField(max_length=32, null=True, blank=True)
address = models.CharField(max_length=255, null=True, blank=True)
number = models.CharField(max_length=32, null=True, blank=True)
city = models.CharField(max_length=50, null=True, blank=True)
zip = models.CharField(max_length=30, null=True, blank=True)
@property
def get_avatar(self):
return self.avatar.url if self.avatar else static('static/MCARS/img/avatars/default.jpg')
def save(self, **kwargs):
if not self.pk:
super(Profile, self).save(**kwargs)
rank = Rank.objects.create(user=self, longrank='o1', shortrank='o1', branch='r')
rank.save()
else:
super(Profile, self).save(**kwargs)
def __str__(self):
rank = Rank.objects.get(user=self.user.profile).get_longrank_display()
return rank + " " + self.user.first_name + " " + self.user.last_name + "(" + self.memberId + ")"
class Rank (models.Model):
user = models.ForeignKey(Profile, related_name="Rank", on_delete=models.CASCADE)
longrank = models.CharField(max_length=5, null=True, blank=True, choices=constants.long_rank)
shortrank = models.CharField(max_length=5, null=True, blank=True, choices=constants.short_rank)
branch = models.CharField(max_length=5, null=True, blank=True, choices=constants.branch)
image = models.ImageField(upload_to="static/MCARS/img/ranks", null=True, blank=True)
history = HistoricalRecords()
def save(self, **kwargs):
self.shortrank = self.longrank
self.image = 'static/MCARS/img/ranks/' + self.branch[0] + '-' + self.longrank + '.png'
super(Rank, self).save(**kwargs)
def __str__(self):
return self.get_longrank_display() + ' (' + self.get_shortrank_display() + ') ' + self.user.user.first_name + ' ' + self.user.user.last_name
class Command (MP_Node):
CO = models.ForeignKey(User, related_name="user", on_delete=models.CASCADE)
ship = models.ImageField(upload_to="static/MCARS/img/ships", null=True, blank=True)
seal = models.ImageField(upload_to="static/MCARS/img/flag", null=True, blank=True)
Type = models.CharField(max_length=10, choices=constants.CMD_TYPE)
name = models.CharField(max_length=255, null=True, blank=True)
address = models.CharField(max_length=255, null=True, blank=True)
number = models.CharField(max_length=32, null=True, blank=True)
city = models.CharField(max_length=50, null=True, blank=True)
zip = models.CharField(max_length=30, null=True, blank=True)
hull = models.CharField(max_length=255, null=True, blank=True)
Commissioned = models.BooleanField(default=True)
node_order_by = ['name']
def save(self, **kwargs):
if not self.pk:
super(Command, self).save(**kwargs)
CommandPositions = CommandPositions.objects.create(command=self, name="CO", responsibility='Commanding Officer')
CommandPositions.save()
else:
super(Command, self).save(**kwargs)
def isCO(self, user):
return self.CO == user
def __str__(self):
rank = Rank.objects.get(user=self.CO.profile).get_longrank_display()
return self.name + ' (' + self.hull + ') ' + rank + " " + self.CO.first_name + " " + self.CO.last_name + " Commanding"
class CommandPositions(models.Model):
Command = models.ForeignKey(Command, related_name="Positions", on_delete=models.CASCADE)
name = models.CharField(max_length=255, null=True, blank=True)
responsibility = models.TextField(null=True, blank=True)
class Assignment (models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
Position = models.ForeignKey(Command, on_delete=models.CASCADE)
assigned_dt = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = "Assignments"
In this solution, when I create a new Profile
, a new Rank
is created. This works. However, when I create a new Command
, a new CommandPositions
record is needed. I tried it the same way as the Profile
/Rank
relationship was done, but it's throwing an error saying that it's not there.
How Come Profile
/Rank
worked, but Command
/CommandPositions
is saying I cannot do that?
when I create a Command
, this error comes up:
File "/Users/evancutler/PycharmProjects/MCARS/MCARS/models.py", line 98, in save
CommandPositions = CommandPositions.objects.create(command=self, name="CO", responsibility='Commanding Officer')
^^^^^^^^^^^^^^^^
Exception Type: UnboundLocalError at /admin/MCARS/command/add/
Exception Value: cannot access local variable 'CommandPositions' where it is not associated with a value
This error does not occur when doing Profile
/Rank
, but it does here.
Any wisdom would be greatly appreciated. Thanks!
Consider your two different cases:
rank = Rank.objects.create(user=self, longrank='o1', shortrank='o1', branch='r')
rank.save()
CommandPositions = CommandPositions.objects.create(command=self, name="CO", responsibility='Commanding Officer')
CommandPositions.save()
Notice anything different?
It's subtle, and there's a missing piece:
class CommandPositions(models.Model):
So what your code essentially does, is you're trying to bind a variable (CommandPositions
the variable in .save()
) to a name that's already in use (CommandPositions
the class definition). Python interpreter thinks you're off your rocker, so it ignores this, because otherwise many other bad things will happen.
# Or pick any variable name you want
# as long as it's not something already in use in this scope
command_positions = CommandPositions.objects.create(command=self, name="CO", responsibility='Commanding Officer')
command_positions.save()