Hello,

Are there any comments on the issue I describe below?
Aside from issue 7052 in the tracker:

http://code.djangoproject.com/ticket/7052

I'm a new user of Django so I may be doing something
wrong.

I hope line wrapping doesn't ruin any code...

Thanks
Mark

====

Using Content Types With Test Databases

Related issue: http://code.djangoproject.com/ticket/7052

Dumping an app's database tables using the 'manage.py dumpdata'
command produces some problems when the ContentTypes app
is used.

The content types application is a contribution to the
Django product.  It is described in:

http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#ref-contr
ib-contenttypes

Content types are mostly automatic and an entry
for each model is made when a model is added to the
database.  This happens normally and during the creation
of the test database when tests are run using manage.py test.

Unfortunately, the content types in a development database
seem to almost always differ from those created in the test
database.  This makes any dumpdata output containing content_type
fields mostly useless.

A workaround for this is to have any data model which uses
a content_type ForeignKey to implement a save method that
autosets the content_type field:

    # We need a special save method to set the content_type.
    def save(self, force_insert=False, force_update=False):
        self.content_type =
ContentType.objects.get(app_label=os.path.basename(os.path.dirname
(__fil
e__)), model=self.__class__.__name__.lower())
        super(Party, self).save(force_insert, force_update) # Call the
"real" save() method.


This workaround requires a script to remove any content_type
fields listed in a JSON dumpdata fixture file.

Fixtures must be dumped with the --indent=2 option
on the dumpdata command.  The default JSON format will
be used.

manage.py dumpdata --indent=2 [appname] > initial_data.json

This python script will strip the content_type entries
from the fixture file.

strip_contenttypes.py
=====================

#!/usr/bin/env python
#
# Mark V. Giovannetti 2008-12-14
# $Id$
# $URL$

# This script removes content_type fields from a django
# fixture file.

# Usage: strip_contenttypes.py json_file [, json_file]
#
# A backup file with an extension of '.with_content_types'
# is created for any input files.

import fileinput
import re, string

# This pattern matches a content_type line.
ct_pattern = re.compile('^\s+"content_type":')

# This pattern matches a content_type line that
# has a comma so that case can be handled by not
# removing the preceding comma.
ct_pattern_with_comma = re.compile('^\s+"content_type":\s+\d+\s*,\s*
$')

# This pattern is to match and replace a trailing
# comma before the content_type field.
trailing_comma_pattern = re.compile(',\s*$')

# This pattern is to match the last bracket in
# the json file and print it.
last_line_pattern = re.compile('^\s*]\s*$')

# We have to cope with the trailing comma on the
# line preceding the content_type line, so we must
# buffer two lines.
line1 = u''
line2 = u''

json_file = fileinput.input(inplace=1, backup='.with_content_types')

for line in json_file:

    # remove the newline from the end of the line
    line = string.rstrip(line)

    # Check if we are at the first line, if so, set the
    # line2 to be this line and depend on the initial blank
    # value set for line1.
    if json_file.isfirstline():
        line2 = line
        # We continue since the first line will never have a
        # content_type marker.
        continue
    else:
        # Move line1 to line2 and set the new line2 to the
        # line just read.
        line1 = line2
        line2 = line

    # Look for the content_type pattern in line2
    if ct_pattern.match(line2):

        # Don't alter line1 if the content_type line has a comma.
        if ct_pattern_with_comma.match(line2):
            line2 = u''
        else:
            line2 = u''
            line1 = trailing_comma_pattern.sub('', line1, count=1)

    # We don't bother printing a blank line.
    if line1: print line1

    # We have to output the last line within this loop
    # since once the json_file is closed the inplace edit
    # stops.  Let's hope the last line is always the closing
    # bracket ].
    if last_line_pattern.match(line):
        print line2


============

Further, in order to have the model's actual save method
called, the base.py file in django\core\serializers must
have its DeserializedObject class' save method modified:

C:\Python25\Lib\site-packages\django\core\serializers\base.py

class DeserializedObject(object):
    """
    A deserialized model.

    Basically a container for holding the pre-saved deserialized data
along
    with the many-to-many data saved with the object.

    Call ``save()`` to save the object (with the many-to-many data) to
the
    database; call ``save(save_m2m=False)`` to save just the object
fields
    (and not touch the many-to-many stuff.)
    """

    def __init__(self, obj, m2m_data=None):
        self.object = obj
        self.m2m_data = m2m_data

    def __repr__(self):
        return "<DeserializedObject: %s>" % smart_str(self.object)

    def save(self, save_m2m=True):
        # Call save on the Model baseclass directly. This bypasses any
        # model-defined save. The save is also forced to be raw.
        # This ensures that the data that is deserialized is literally
        # what came from the file, not post-processed by pre_save/save
        # methods.

        # M. Giovannetti 2008-12-14
        # Call the object's save method to handle content_type
        # problems.  The law of unintended consequences applies
        # here.
        self.object.save()
        #models.Model.save_base(self.object, raw=True)

        if self.m2m_data and save_m2m:
            for accessor_name, object_list in self.m2m_data.items():
                setattr(self.object, accessor_name, object_list)

        # prevent a second (possibly accidental) call to save() from
saving
        # the m2m data twice.
        self.m2m_data = None

--~--~---------~--~----~------------~-------~--~----~
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?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to