Have created model (below) which doesn't report any errors in admin, but
unfortunately doesn't work either. Behaviour as follows:
1. Create instance of Server in admin;
2. Populate core server fields;
3. Create a couple of Product Deployments;
4. Save
On returning to edit the server, the core server details are correct -
but none of the deployments has been recorded. Examining the db shows
no entries in the intersection table used to record the m2m mapping.
Tried from the shell and all works OK - as long as the Deployment
instance is saved before the m2m mapping instances are added.
Otherwise, there's an exception.
Would appreciate any help; e.g. is this a valid use of the admin
interface? (From the shell trace it looks like the Deployment has to be
saved before adding the referenced packages, maybe admin doesn't do this?)
Thanks,
Scoot.
--
model.py
--------
"""
Simple model for recording inventory of systems deployed.
ProductVersion is specification class describing the products that can
be deployed; Servers are the physical hosts; PackageDeployments map
software packages (instances of ProductVersion) to the Servers on which
they're deployed (M2M).
"""
from django.db import models
PRODUCT_TYPE = (
('hw', 'Hardware'),
('os', 'Operating System'),
('pkg', 'Application Package')
)
ENVIRONMENT = (
('prod', 'Production'),
('ppd', 'Pre-production'),
('test', 'Test'),
('dev', 'Development')
)
class ProductVersion(models.Model):
"""Describes prducts: hardware models, operating systems,
software packages. """
class Admin:
list_display=('name',)
search_fields = ('name',)
ordering = ('name',)
name = models.CharField("Name", maxlength=100, core=True)
pvtype = models.CharField("Type", maxlength=100,
core=True, choices=PRODUCT_TYPE)
def __str__(self):
return self.name
class Server(models.Model):
"""A server hosting various software packages"""
class Admin:
list_display=('name', 'mdl', 'os',)
search_fields = ('name',)
ordering = ('name',)
fields = (
(None, {'fields': ('name', 'mdl', 'os',)}),
)
name = models.CharField("Name", maxlength=100, core=True)
mdl = models.ForeignKey(ProductVersion,
verbose_name="model",
related_name="modelOf",
limit_choices_to = {'pvtype__exact' : "hw"},
core=True)
os = models.ForeignKey(ProductVersion,
verbose_name="Operating System",
related_name="osOn",
limit_choices_to = {'pvtype__exact' : "os"},
core=True)
def __str__(self):
return(self.name)
class PackageDeployment(models.Model):
""" Represents deployment of a set of software packages on a server
"""
description = models.CharField("Description", maxlength=100,
core=True, blank=True, null=True)
environment = models.CharField("Environment", maxlength=100,
core=True, choices=ENVIRONMENT)
server = models.ForeignKey(Server,
edit_inline=models.TABULAR,
num_in_admin=3,
verbose_name="Server",
related_name="hostFor",
core=True)
packages = models.ManyToManyField(ProductVersion,
verbose_name="Packages",
related_name="deployedOn",
limit_choices_to =
{'pvtype__exact' : "pkg"},
core=True)
def __str__(self):
return self.server.name + "-" + self.environment
------------------------------------------------------------------
Shell trace
-----------
>>> from scratch1.scratchapp.models import *
>>> hwmdl=ProductVersion(name="Server Model", pvtype="hw")
>>> hwmdl.save()
>>> osmdl=ProductVersion(name="linux", pvtype="os")
>>> osmdl.save()
>>> pkg1=ProductVersion(name="Package 1", pvtype="pkg")
>>> pkg1.save()
>>> pkg2=ProductVersion(name="Package 2", pvtype="pkg")
>>> pkg2.save()
>>> pkg3=ProductVersion(name="Package 3", pvtype="pkg")
>>> pkg3.save()
>>> srvr=Server(name="Server 1", mdl=hwmdl, os=osmdl)
>>> srvr.save()
>>> pd1=PackageDeployment(environment='ppd', server=srvr)
>>> # save before adding referenced packages: success
>>> pd1.save()
>>> pd1.packages.add(pkg1, pkg2)
>>> pd1.save()
>>> pd1.packages.all()
[<ProductVersion: Package 1>, <ProductVersion: Package 2>]
>>> # no save before adding referenced packages: fails
>>> # error msg indicates problem with ProductVersion pk,
>>> # not sure why...
>>> pd2=PackageDeployment(environment='ppd', server=srvr)
>>> pd2.packages.add(pkg2, pkg3)
Traceback (most recent call last):
File "<console>", line 1, in ?
File
"/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/fields/related.py",
line 439, in __get__
target_col_name=qn(self.field.m2m_reverse_name())
File
"/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/fields/related.py",
line 278, in __init__
raise ValueError("%r instance needs to have a primary key value
before a many-to-many relationship can be used." % model)
ValueError: <class 'scratch1.scratchapp.models.ProductVersion'> instance
needs to have a primary key value before a many-to-many relationship can
be used.
>>> #save and retry adding: OK.
>>> pd2.save()
>>> pd2.packages.add(pkg2, pkg3)
>>> pd2.save()
>>> pd2.packages.all()
[<ProductVersion: Package 2>, <ProductVersion: Package 3>]
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-users
-~----------~----~----~----~------~----~------~--~---