I have a form which is collecting data about a variable to be created. I want to create a list of variables which are already there in the database. I am doing this by creating a ManyToMany relationship. When I start the server, the list of variables gets saved on the application, but it does not alter the database field named selective list.
forms.py
class VariableForm(ModelForm):
class Meta:
model = variable
fields = ['name', 'area', 'parameterName', 'order', 'type', 'format', 'units', 'comboItems',
'hiAlarm', 'loAlarm', 'scaleHiMax', 'scaleLoMax', 'deviationAlarm','selectiveList', 'round',
'days', 'required', 'hidden', 'readOnly', 'holdLast', 'calibrationFrequency',
'dateNextCalibration', 'triggerCalibrated']
widgets = {
'comboItems': forms.Textarea(attrs={'rows':1, 'cols': 40, 'style': 'height: 2em;padding-top:0'}),
'forceValue': forms.Textarea(attrs={'rows':1, 'cols': 40, 'style': 'height: 2em;padding-top:0',
'placeholder':'This will force all input to this variable'})
}
#selectiveList = forms.ModelMultipleChoiceField(queryset=variable.objects.all().order_by('-name').reverse())
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(VariableForm, self).__init__(*args, **kwargs)
self.fields['round'] = forms.ModelMultipleChoiceField(
queryset=opRound.objects.all(),
widget=forms.SelectMultiple,
label='Rounds',
required=False
)
self.fields['selectiveList'] = forms.ModelMultipleChoiceField(
queryset=variable.objects.all().order_by('-name').reverse(),
widget=forms.SelectMultiple,
label='Select Variables',
required=False
)
self.fields['days'] = forms.ModelMultipleChoiceField(
queryset=dayOfWeek.objects.all(),
widget=forms.SelectMultiple,
label='Days',
required=False
)
self.fields['area'].choices = AreaIterator(request = self.request)
try:
self.fields['order'].initial = variable.objects.latest().order+1
except Exception,e:
print e
model.py
class variable(models.Model):
name = models.CharField(max_length=255)
area = models.ForeignKey(area)#parent
order = models.IntegerField("Order Index (0 is first, 1 is next, etc.)",default=999)#order index to display in order correctly, ascending
type = models.CharField(max_length=255, choices=(("Value", "Value"), ("Runtime", "Runtime/FlowTotal"),
("Message", "Message"), ("CheckBox", "Check Box List"), ("Selection", "Selection Box"), ("Formula2", "Formula with other Variables"),
("OnOff", "In/Out of Service Selection"), ("OnOffSelection", "Selective On/Off")),
default = "Value" )#what type of variable
format = models.CharField(max_length=255,choices=(("Number", "Number (Without Decimals)"),
("2Number", "Number (With Decimals)"), ("Date", "Date"),
("Time", "Time"), ("Text", "Text")), blank=True, null=True, default="2Number" )#number format if needed
units = models.CharField(max_length=255,blank=True,null=True)#units of measurement
required = models.BooleanField(default=True)#is the variable required in a round
hiAlarm = models.FloatField("High Alarm",blank=True,null=True)#red notify if above
loAlarm = models.FloatField("Low Alarm",blank=True,null=True)#yellow notify if below
scaleHiMax = models.FloatField("Limit maximum value",blank=True,null=True)#scale to high max if needed
scaleLoMax = models.FloatField("Limit low value",blank=True,null=True)#scale to low if needed
deviationAlarm = models.FloatField("Deviation Alarm",blank=True,null=True,
help_text="Triggers an alarm if the value between this record and the last is greater than this percentage.")#%change check
round = models.ManyToManyField(opRound,blank=True)#round of gathering data
days = models.ManyToManyField(dayOfWeek,blank=True)#day of the week
selectiveList = models.ManyToManyField("self",through="variable",blank=True,symmetrical=False)#List to determine which variables to display when the selection is "OFF"
parameterName = models.CharField("Parameter Name (ReportID)",max_length=255,blank=True,null=True)#hachWIM ID
comboItems = models.TextField("List of comma separated options.", blank=True,null=True)#list deliminated by a column for choosing
#PUT EQUATION HERE
hidden = models.BooleanField("Sync to tablet",default=True)#this muse be True if required is true
readOnly = models.BooleanField("Read only.", default = False)
dateTimeEdited = models.DateTimeField(auto_now=True)#date edited
userEdited = models.ForeignKey(CustomUser,blank=True,null=True,related_name="userEditedV")# last user to edit data
forceValue = models.TextField(blank=True,null=True)#force reading
userForced = models.ForeignKey(CustomUser,blank=True,null=True,related_name="userForcedV")# last user to force data
useForce = models.BooleanField("Turn Forcing On", default=False)
dateNextCalibration = models.DateField("Next Calibration Date", blank=True,null=True, help_text="YYYY-MM-DD")
triggerCalibrated = models.BooleanField("Trigger next calibration date", default=False)
calibrationFrequency = models.ForeignKey(calibrationFrequency, blank=True, null=True)
version = models.BigIntegerField(default=1)#used for sync
holdLast = models.BooleanField("Selecting this will hold the last value on the tablet automatically.", default=False)
When we are trying to do it from different models, such as round or days, it creates a new database table with those relations. I want to store the selected values as a string list in the selective list column in the same model.
Here is what the multiple select looks like.
I have the following models :
class criterion(models.Model):
quantity = '0'
quality = '1'
ascending = '0'
descending = '1'
three = '3'
five = '5'
seven = '7'
ten = '10'
type_choices = (
(quantity,'Ποσοτικό'),
(quality,'Ποιοτικό'),
)
monotonicity_choices = (
(ascending,'Αύξον'),
(descending,'Φθίνον'),
)
a_choices = (
(three,'Τριβάθμια'),
(five,'Πενταβάθμια'),
(seven,'Εφταβάθμια'),
(ten,'Δεκαβάθμια'),
)
criterion_research = models.ForeignKey('research', on_delete=models.CASCADE,null=True)
criterion_name = models.CharField(max_length = 200,verbose_name='Όνομα Κριτηρίου')
criterion_type = models.CharField(max_length = 15,choices = type_choices , default = quantity,verbose_name='Τύπος')
criterion_monotonicity = models.CharField(max_length = 15,choices = monotonicity_choices , default = ascending,verbose_name='Μονοτονία')
criterion_a = models.CharField(max_length = 30,choices = a_choices , default = five,verbose_name='Κλίμακα',help_text='Επιλέξτε μία από τις 4 κλίμακες που θα μετρηθεί το κριτήριο.')
criterion_worst = models.FloatField(default=' ',verbose_name='Χειρότερη Τιμή',help_text='Επιλέξτε τη χειρότερη τιμή την οποία μπορεί να πάρει το κριτήριο.',blank=True)
criterion_best = models.FloatField(default=' ',verbose_name='Καλύτερη Τιμή',help_text='Επιλέξτε τη καλύτερη τιμή την οποία μπορεί να πάρει το κριτήριο.',blank=True)
def __str__(self):
return self.criterion_name
class alternative(models.Model):
name = models.CharField(max_length = 200,verbose_name='Όνομα Εναλλακτικής')
ranking = models.IntegerField(default='1')
alternative_research = models.ForeignKey('research', on_delete=models.CASCADE)
criteria = models.ManyToManyField('criterion', through='criterionvalue',blank=True)
def __str__(self):
return self.name
class criterionvalue(models.Model):
value = models.IntegerField(default='0')
alt = models.ForeignKey('alternative',on_delete=models.CASCADE)
crit = models.ForeignKey('criterion',on_delete=models.CASCADE)
I have made a view that populates the criterion instances and the alternative instances(except the manytomany field).
I want to query for all the possibles criterion and alternatives and then based on that populate the criterionvaue instances.After I complete these I want then to specify the manytomany relatioship of the criterionvalue instances with the alternatives instances .I thought of making a formset of criterionvalue model then associate them(the forms made by the formset) with the alternatives and criteria using the length of the alternatives and criteria queryset(In order to render the relatioship matrix using forms) .
But I think such an idea is farfetched.
Any ideas on how i could achieve such thing ?
I want to find attributes associated to my character that fit in various categories. Eventually I want this output:
"Attributes": {
"Physical": {
"Level": 1,
"Strength": 1,
"Dexterity": 1,
"Stamina": 1
},
"Mental": {
"Level": 2,
"Intelligence": 1,
"Wits": 1,
"Resolve": 1
},
"Social": {
"Level": 3,
"Presence": 1,
"Manipulation": 1,
"Composure": 1
}
},
I have an Class/Enum(AutoNumber) with the attributes in, and a method of finding which is which:
class AttributeAbility(models.Model):
class Attributes(AutoNumber):
INTELLIGENCE = () # Mental, Power
WITS = () # Mental', 'Finesse
RESOLVE = () # Mental', 'Resistance
STRENGTH = () # Physical', 'Power
DEXTERITY = () # Physical', 'Finesse
STAMINA = () # Physical', 'Resistance
PRESENCE = () # Social', 'Power
MANIPULATION = () # Social', 'Finesse
COMPOSURE = () # Social', 'Resistance
attribute = EnumField(Attributes)
#property
def attribute_type(self):
attribute_group = lambda attribute: (
int((attribute.value - 1) / 8)) + 1 % 3
return Category(attribute_group(self.attribute))
class Category(AutoNumber):
MENTAL = ()
PHYSICAL = ()
SOCIAL = ()
I connect the AttributeAbility with my character using these classes:
class CrossCharacterMixin(models.Model):
cross_character_types = models.Q(app_label='mage', model='mage')
content_type = models.ForeignKey(ContentType, limit_choices_to=cross_character_types,
null=True, blank=True)
object_id = models.PositiveIntegerField(null=True)
content_object = GenericForeignKey('content_type', 'object_id')
class Meta:
abstract = True
class CharacterAttributeLink(Trait, CrossCharacterMixin):
MIN = 1
PRIORITY_CHOICES = (
(0, 'Unassigned'), (1, 'Primary'), (2, 'Secondary'), (3, 'Tertiary')
)
attribute = models.ForeignKey('AttributeAbility')
priority = models.PositiveSmallIntegerField(
choices=PRIORITY_CHOICES, default=0
)
def __str__(self):
return self.attribute.attribute.label
And then on the Mage I have:
attributes = GenericRelation('CharacterAttributeLink')
#property
def physical_attributes(self):
type_id = Category['PHYSICAL']
return self.attributes.filter(attribute_type=type_id)
But I'm getting the error that: Cannot resolve keyword 'attribute_type' into field. Choices are: attribute, attribute_id, content_type, content_type_id, current_value, id, maximum_value, object_id, priority
And with my function like so:
#property
def physical_attributes(self):
type_id = Category['PHYSICAL']
return self.attributes.filter(attribute__attribute_type=type_id)
I get this error: Related Field got invalid lookup: attribute_type Which makes some sense (though I've seen this in the docs: >>> Entry.objects.filter(blog_id=4)).
Adding __exact on the end, gives me this: Relation fields do not support nested lookups....at which point I'm lost. Do I need a custom manager? Do I need to move my physical_attribute function elsewhere?
I ended up creating a custom manager:
class CategoryManager(models.Manager):
'''
Class to manage instances that rely on the category enum
'''
def physical(self):
return [categorised_item for categorised_item in super(CategoryManager, self).get_queryset().all()
if categorised_item.category == Category['PHYSICAL']]
def mental(self):
return [categorised_item for categorised_item in super(CategoryManager, self).get_queryset().all()
if categorised_item.category == Category['MENTAL']]
def social(self):
return [categorised_item for categorised_item in super(CategoryManager, self).get_queryset().all()
if categorised_item.category == Category['SOCIAL']]
And then adding this to my AttributeAbility model:
objects = CategoryManager()
And defining this property on my character model:
#property
def social_skills(self):
return [self.skills.filter(skill=skill) for skill
in SkillAbility.objects.social()]
Under Django, for a project that worked with previous versions of Python and Django (read: maybe this is a porting question), I get:
CommandError: One or more models did not validate:
directory.phone: Reverse query name for field 'entity' clashes with field 'Entity.phone'. Add a related_name argument to the definition for 'entity'.
What do I need to do? My models.py file is below:
#!/usr/bin/python
# coding = UTF-8
from django.contrib import admin
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.db import models
import datetime
import directory
import django.forms
import re
OFFICE_CHOICES = (
(u'CN', u'Chicago North Office, Illinois, USA'),
(u'CS', u'Chicago South Office, Illinois, USA'),
(u'WH', u'Wheaton Office, Illinois, USA'),
(u'SY', u'Sydney Office, New South Wales, Australia'),
)
EDIT_CHOICES = (
(u'a', u'Foreign key relationship changed.'),
(u'b', u'Image changed.'),
(u'c', u'Instance created.'),
(u'd', u'Instance deleted.'),
(u'e', u'Many to many relationship added.'),
(u'f', u'Many to many relationship deleted.'),
(u'g', u'One to many relationship added.'),
(u'h', u'One to many relationship deleted.'),
(u'i', u'Text changed.'),
)
TIME_ZONE_CHOICES = (
(None, "Select"),
("1.0", "A: Paris, +1:00"),
("2.0", "B: Athens, +2:00"),
("3.0", "C: Moscow, +3:00"),
("4.0", "D: Dubai, +4:00"),
("4.5", "-: Kabul, +4:30"),
("5.0", "E: Karachi, +5:00"),
("5.5", "-: New Delhi, +5:30"),
("5.75", "-: Kathmandu, :5:45"),
("6.0", "F: Dhaka, +6:00"),
("6.5", "-: Rangoon, +6:30"),
("7.0", "G: Jakarta, +7:00"),
("8.0", "H: Kuala Lumpur, +8:00"),
("9.0", "I: Tokyo, +9:00"),
("9.5", "-: Adelaide, +9:30"),
("10.0", "K: Sydney, +10:00"),
("10.5", "-: Lord Howe Island, +10:30"),
("11.0", "L: Solomon Islands, +11:00"),
("11.5", "-: Norfolk Island, +11:50"),
("12.0", "M: Auckland, +12:00"),
("12.75", "-: Chatham Islands, +12:45"),
("13.0", "-: Tonga, +13:00"),
("14.0", "-: Line Islands, +14:00"),
("-1.0", "N: Azores, -1:00"),
("-2.0", "O: Fernando de Norohna, -2:00"),
("-3.0", "P: Rio de Janiero, -3:00"),
("-3.5", "-: St. John's, -3:50"),
("-4.0", "Q: Santiago, -4:00"),
("-4.5", "-: Caracas, -4:30"),
("-5.0", "R: New York City, -5:00"),
("-6.0", "S: Chicago, -6:00"),
("-7.0", "T: Boulder, -7:00"),
("-8.0", "U: Los Angeles, -8:00"),
("-9.0", "V: Anchorage, -9:00"),
("-9.5", "-: Marquesas Islands, -9:30"),
("-10.0", "W: Hawaii, -10:00"),
("-11.0", "X: Samoa, -11:00"),
("-12.0", "Y: Baker Island, -12:00"),
("0.0", "Z: London, +0:00"),
)
FOREIGN_KEY_RELATIONSHIP_CHANGED = u'a'
IMAGE_CHANGED = u'b'
INSTANCE_CREATED = u'c'
INSTANCE_DELETED = u'd'
MANY_TO_MANY_RELATIONSHIP_ADDED = u'e'
MANY_TO_MANY_RELATIONSHIP_DELETED = u'f'
MANY_TO_ONE_RELATIONSHIP_ADDED = u'g'
MANY_TO_ONE_RELATIONSHIP_DELETED = u'h'
TEXT_CHANGED = u'i'
class EditTrail(models.Model):
change_set = models.IntegerField()
change_type = models.CharField(max_length = 1, choices = EDIT_CHOICES)
content_object = generic.GenericForeignKey(u'content_type', u'object_id')
content_type = models.ForeignKey(ContentType)
field_name = models.TextField(null = True, blank = True)
foreign_key_added = generic.GenericForeignKey()
foreign_key_deleted = generic.GenericForeignKey()
in_effect = models.BooleanField()
instance = generic.GenericForeignKey()
ip = models.IPAddressField()
object_id = models.PositiveIntegerField()
session = models.TextField(null = True, blank = True)
text_after = models.TextField(null = True, blank = True)
text_before = models.TextField(null = True, blank = True)
timestamp = models.DateTimeField(default = datetime.datetime.now, blank =
True)
username = models.TextField(null = True, blank = True)
def format_timestamp(self):
return directory.functions.format_timestamp(self.timestamp)
class ExtensionField(models.TextField):
def __init__(self, *arguments, **keywords):
models.TextField.__init__(self, *arguments, **keywords)
def gps_validator(value):
# Create a normalized working copy of the value.
working_copy = value
working_copy = working_copy.replace(u'\n', u',')
working_copy = working_copy.replace(u'\r', u',')
working_copy = re.sub(ur',*$', '', working_copy)
working_copy = re.sub(ur',+', u',', working_copy)
if not u',' in working_copy and not \
re.match(ur'.* .* .*', working_copy):
working_copy = working_copy.replace(u' ', u',')
working_copy = re.sub(u'[\00B0\2018\2019\201C\201D\'"]', ' ', working_copy)
working_copy = working_copy.replace(u',', u', ')
working_copy = re.sub(ur'\s+', u' ', working_copy)
working_copy = working_copy.strip()
working_copy = working_copy.upper()
# Test the normalized working copy against regular expressions for different kinds of GPS format.
if re.match(ur'[-NS]? ?\d{1,3} [0-5]\d [0-5]\d(\.\d+)[NS]?, [-EW]? ?\d{1,3} [0-5]\d [0-5]\d(\.\d+)[EW]?', working_copy):
return working_copy
elif re.match(ur'[-NS]? ?\d{1,3} [0-5]\d(\.\d+)[NS]?, [-EW]? ?\d{1,3} [0-5]\d(\.\d+)[EW]?', working_copy):
return working_copy
elif re.match(ur'[-NS]? ?\d{1,3}(\.\d+)[NS]?, [-EW]? ?\d{1,3}(\.\d+)[EW]?', working_copy):
return working_copy
else:
raise ValidationError(u'We could not recognize this as a valid GPS coordinate.')
class GPSField(models.TextField):
default_error_messages = {
u'invalid': u'We could not recognize this as a valid GPS coordinate.',
}
default_validators = [gps_validator]
class Increment(models.Model):
pass
class Location(models.Model):
identifier = models.TextField(blank = True)
description = models.TextField(blank = True)
office = models.CharField(max_length=2, choices=OFFICE_CHOICES, blank =
True)
postal_address = models.TextField(blank = True)
room = models.TextField(blank = True)
coordinates = GPSField(blank = True)
class TextURLField(models.URLField):
def __init__(self, *arguments, **keywords):
models.URLField.__init__(self, *arguments, **keywords)
def get_internal_type(self):
return u'TextField'
# This class is basically the "Person" class; however, it is called "Entity"
# to emphasize that it is intended to accommodate people, offices,
# organizational units, and possibly other areas.
class Entity(models.Model):
active = models.BooleanField(blank = True)
department = models.ForeignKey(u'self', blank = True, null =
True, related_name = u'member')
description = models.TextField(blank = True)
gps = GPSField()
image_mimetype = models.TextField(blank = True, null = True)
is_invisible = models.BooleanField(default = False)
location = models.ForeignKey(u'self', blank = True, null = True,
related_name = u'occupant')
name = models.TextField(blank = True, default =
directory.settings.PLACEHOLDER_NAME)
observes_daylight_saving_time = models.BooleanField(blank = True, default
= True)
other_contact = models.TextField(blank = True)
postal_address = models.TextField(blank = True)
publish_externally = models.BooleanField(blank = True)
reports_to = models.ForeignKey(u'self', blank = True, null = True,
related_name = u'subordinate')
start_date = models.DateField(blank = True, null = True)
time_zone = models.CharField(max_length = 5, null = True, choices =
TIME_ZONE_CHOICES)
title = models.TextField(blank = True)
class Meta:
permissions = (
("view_changelog", "View the editing changelog"),
)
class Tag(models.Model):
entity = models.ForeignKey(Entity)
is_invisible = models.BooleanField(default = False)
text = models.TextField(blank = True)
def __eq__(self, other):
try:
return self.text == other.text
except:
return False
class TextEmailField(models.EmailField):
#entity = models.ForeignKey(Entity)
def __init__(self, *arguments, **keywords):
models.EmailField.__init__(self, *arguments, **keywords)
def get_internal_type(self):
return u'TextField'
class Email(models.Model):
email = TextEmailField()
entity = models.ForeignKey(Entity)
is_invisible = models.BooleanField(default = False)
class URL(models.Model):
entity = models.ForeignKey(Entity)
url = TextURLField()
is_invisible = models.BooleanField(default = False)
class Phone(models.Model):
description = models.TextField(blank = True, null = True)
entity = models.ForeignKey(Entity, blank = True)
is_invisible = models.BooleanField(default = False)
number = models.TextField(blank = True)
def __eq__(self, other):
try:
return self.remove_formatting() == other.remove_formatting()
except:
return False
def remove_formatting(self):
return re.sub(ur'\D', u'', str(self))
class Status(models.Model):
datetime = models.DateTimeField(default = datetime.datetime.now, blank = True)
entity = models.ForeignKey(Entity, blank = True)
is_invisible = models.BooleanField(default = False)
text = models.TextField(blank = True)
username = models.TextField(blank = True)
def format_timestamp(self):
return directory.functions.format_timestamp(self.datetime)
class EntityForm(django.forms.ModelForm):
class Meta:
model = Entity
fields = (u'name', u'description', u'phone', u'department',
u'postal_address', u'reports_to', u'active', u'publish_externally')
class LocationForm(django.forms.ModelForm):
class Meta:
model = Location
In the Phone definition, for the entity attribute, add this argument:
related_name = "entity_phone"
Django builds automatically reverse relationships in models, and sometimes the names it chooses clash with other existing related names. So you can explicitly set these names so they don't clash.
In your Phone Model
class Phone(models.Model):
entity = models.ForeignKey(Entity, blank = True, related_name="someName")
Firstly try to reset your data base. And delete all your migrations and then run again . If same problem persist. Improve the question .