I am trying to test my own update_or_create method written in Python, but I run into a error, I Googled it and find no answer. Here is the source code:
class ListingManager(models.Manager):#manage the creating/editting/deleting of listings
def update_or_create_listing(self, listing_attributes, scraped = False, **extra_attributes):
from sitebot.tasks import scrape_listing_url
keys = listing_attributes.keys()
print keys
site = Site.objects.get(id = listing_attributes['site_id'])
if 'sku' in keys and 'site_id' in keys and 'url' in keys:
#create a listing if no such listing exists
#SiteUrl.objects.get_or_create(href )
listing, created = self.get_or_create(sku = listing_attributes['sku'], site = site, defaults = {'url': listing_attributes['url']})
dynamo_db_listing_attributes = []
if len(keys)> 3:
dynamo_db_listing_attributes = listing.create_or_update_attributes(listing_attributes = listing_attributes, **extra_attributes)
if scraped == True and listing.scraped == False: #if the listing is already scraped, update the scraped status
listing.scraped = scraped
listing.save()
if created == True and listing.scraped == False: #if the listing is just created and not scraped yet
scrape_listing_url.delay(listing_id = str(listing.id), sku = listing.sku, listing_url = listing.url, scraper_name = listing.site.scraper.name) # what does delay do?
return listing, listing_attributes
else:
raise KeyError
and this is the test code:
class ListingManagerClassTests(TestCase):
def setUp(self):
#Generate Site for listing
site = models.Site()
#Generating Site requires ForeignKey Country
country_for_site = models.Country()
country_for_site.save()
#Generating Site requires ForeignKey Scraper
scraper_for_site = models.Scraper()
scraper_for_site.scrapes_per_day = 1
scraper_for_site.max_results = 10
scraper_for_site.save()
site.country = country_for_site
site.scraper = scraper_for_site
site.name = "siteforListingMangerTest"
site.save()
def test_create_listing(self):
"""update_or_create_listing should return the created listing"""
lm = models.ListingManager()
site = models.Site.objects.get(name="siteforListingMangerTest")
listing_attributes = {'sku':'123456','site_id':site.id,
'url':'www.aaa.com'}
#Create the new listing
created_listing, created_listing_attributes = lm.update_or_create_listing(listing_attributes,False)
#check if the retreived listing is the right one
assertEqual(created_listing.sku, '123456')
assertEqual(created_listing.site, site)
assertEqual(created_listing.url,'www.aaa.com')
and the error is:
ERROR: test_create_listing (sitebot.tests.ListingManagerClassTests)
update_or_create_listing should return the created listing
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/wx2228/Desktop/BestBot/bestbot/sitebot/tests.py", line 35, in test_create_listing
created_listing, created_listing_attributes = lm.update_or_create_listing(listing_attributes,False)
File "/home/wx2228/Desktop/BestBot/bestbot/sitebot/models.py", line 90, in update_or_create_listing
listing, created = self.get_or_create(sku = listing_attributes['sku'], site = site, defaults = {'url': listing_attributes['url']})
File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 127, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 402, in get_or_create
lookup, params = self._extract_model_params(defaults, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 457, in _extract_model_params
for f in self.model._meta.fields:
AttributeError: 'NoneType' object has no attribute '_meta'
source code for Listing:
class Listing(models.Model):#representing the listing of an product
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
dynamoDB_connection = DynamoDBConnection(region=RegionInfo(name='us-west-2', endpoint='dynamodb.us-west-2.amazonaws.com'))
listings_dynamo_table = Table(table_name = 'sitebot_listings', connection= dynamoDB_connection)
sku = models.CharField(max_length=50)
site = models.ForeignKey(Site)
url = models.CharField(max_length=200, null = True)
scraped = models.BooleanField(default = False)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
objects = ListingManager()
Instantiating the ListingManager directly prevents the query engine to find the underlying object.
You can fix this by replacing the line:
lm = models.ListingManager()
With the line:
lm = Listing.objects
(or maybe)
lm = Listing.objects.all()
Anyway, you need to refer to the Manager through the Model itself, otherwise the query manager will get lost.
It should work (I just spent half a day on a similar problem. Gotta love Django magic error messages ;) )
Python is trying to find the field _meta in self.model. When it says that NoneType does not have that attribute, it means that self.model is None at the point you hit that line. You will have to trace back through your code and see why its value would be None at that point.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With