added DjangoItem item class

This commit is contained in:
Ismael Carnales 2009-08-24 17:16:18 -03:00
parent 7b30c31b59
commit decbdc5346
5 changed files with 111 additions and 3 deletions

View File

@ -0,0 +1,37 @@
from scrapy.item import DictItem, Field
class DjangoItemMeta(type):
def __new__(mcs, class_name, bases, attrs):
cls = super(DjangoItemMeta, mcs).__new__(mcs, class_name, bases, attrs)
cls.fields = cls.fields.copy()
if cls.django_model:
cls._model_fields = []
cls._model_meta = cls.django_model._meta
for model_field in cls._model_meta.fields:
# XXX: for now we're treating each PK as autogenerated field
if model_field != cls._model_meta.pk:
cls.fields[model_field.name] = Field()
cls._model_fields.append(model_field.name)
# add declared fields
for n, v in attrs.iteritems():
if isinstance(v, Field):
cls.fields[n] = v
return cls
class DjangoItem(DictItem):
__metaclass__ = DjangoItemMeta
django_model = None
def save(self, commit=True):
modelargs = dict((f, self.get(f, None)) for f in self._model_fields)
model = self.django_model(**modelargs)
if commit:
model.save()
return model

View File

@ -34,9 +34,7 @@ class _ItemMeta(type):
return cls
class Item(DictMixin, BaseItem):
__metaclass__ = _ItemMeta
class DictItem(DictMixin, BaseItem):
fields = {}
@ -81,6 +79,11 @@ class Item(DictMixin, BaseItem):
return "%s(%s)" % (self.__class__.__name__, values)
class Item(DictItem):
__metaclass__ = _ItemMeta
class ScrapedItem(BaseItem):
def __init__(self, data=None):

View File

@ -0,0 +1,56 @@
import os
from twisted.trial import unittest
from scrapy.contrib_exp.djangoitem import DjangoItem, Field
os.environ['DJANGO_SETTINGS_MODULE'] = 'scrapy.tests.test_djangoitem.settings'
try:
from models import Person
django = True
except ImportError:
django = False
class BasePersonItem(DjangoItem):
django_model = Person
class NewFieldPersonItem(BasePersonItem):
other = Field()
class OverrideFieldPersonItem(BasePersonItem):
age = Field(default=1)
class DjangoItemTest(TestCase):
def setUp(
if not django:
raise unittest.SkipTest("Django is not available")
def test_base(self):
i = BasePersonItem()
self.assertEqual(i.fields.keys(), ['age', 'name'])
def test_new_fields(self):
i = NewFieldPersonItem()
self.assertEqual(i.fields.keys(), ['age', 'other', 'name'])
def test_override_field(self):
i = OverrideFieldPersonItem()
self.assertEqual(i.fields.keys(), ['age', 'name'])
self.assertEqual(i.fields['age'], {'default': 1})
def test_save(self):
i = BasePersonItem()
self.assertEqual(i.fields.keys(), ['age', 'name'])
i['name'] = 'John'
i['age'] = '22'
person = i.save(commit=False)
self.assertEqual(person.name, 'John')
self.assertEqual(person.age, '22')

View File

@ -0,0 +1,10 @@
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=255)
age = models.IntegerField()
class Meta:
app_label = 'test_djangoitem'

View File

@ -0,0 +1,2 @@
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = ':memory:'