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 django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users
-~----------~----~----~----~------~----~------~--~---

Reply via email to