Comments (6)
Hi, this issue got reported multiple times already but I cannot reproduce it. Maybe you can help me find the root cause of this? So:
- Can you tell me which Django version you are using
- Can you tell me more about the model that holds the m2m field that is causing the trouble?
from django-autofixture.
Django==1.5.4 (I do not remember exactly, but it seems the problem was with version 1.5.1 too)
class Product(CacheInvalidatorMixin, models.Model):
"""A product is sold within a shop.
Parameters:
- name
The name of the product
- slug
Part of the URL
- sku
The external unique id of the product
- price
The gross price of the product
- effective_price:
Only for internal usage (price filtering).
- unit
The unit of the product. This is displayed beside the quantity
field.
- price_unit
The unit of the product's price. This is displayed beside the price
- short_description
The short description of the product. This is used within overviews.
- description
The description of the product. This is used within the detailed view
of the product.
- images
The images of the product.
- meta_title
the meta title of the product (the title of the HTML page).
- meta_keywords
the meta keywords of the product.
- meta_description
the meta description of the product.
- related_products
Related products for this products.
- accessories
Accessories for this products.
- active
If False the product won't be displayed to shop users.
- creation_date
The creation date of the product
- deliverable
If True the product is deliverable. Otherwise not.
- manual_delivery_time
If True the delivery_time of the product is taken. Otherwise the
delivery time will be calculate on global delivery times and
selected shipping method.
- delivery_time
The delivery time of the product. This is only relevant if
manual_delivery_time is set to true.
- order_time
Order time of the product when no product is within the stock. This
is added to the product's delivery time.
- ordered_at
The date when the product has been ordered. To calculate the rest of
the order time since the product has been ordered.
- manage_stock_amount
If true the stock amount of the product will be decreased when a
product has been saled.
- weight, height, length, width
The dimensions of the product relevant for the the stock (IOW the
dimension of the product's box not the product itself).
- tax
Tax rate of the product.
- variant_group_id
This field is an integer number used to group products in variant group.
All products that has same variant_group_id are considered to be varaints of each other
- template
Sets the template, which renders the product content. If left to None, default template is used.
"""
# All products
name = models.CharField(_(u"Name"), max_length=128, blank=True)
slug = models.SlugField(_(u"Slug"), unique=True, max_length=80, db_index=True)
sku = models.CharField(_(u"SKU"), blank=True, max_length=64, db_index=True)
price = models.FloatField(_(u"Price"), default=0.0, db_index=True)
cost_price = models.FloatField(_(u"Cost price"), default=0.0)
wholesale_price = models.FloatField(_(u"Wholesale price"), default=0.0)
supplier_price = models.FloatField(_(u"Supplier price"), default=0.0)
effective_price = models.FloatField(_(u"Price"), blank=True) # TODO : store it in session or cache
price_unit = models.CharField(blank=True, max_length=20)
unit = models.CharField(blank=True, max_length=20)
short_description = models.TextField(_(u"Short description"), blank=True)
description = models.TextField(_(u"Description"), blank=True)
images = generic.GenericRelation("Image", verbose_name=_(u"Images"),
object_id_field="content_id", content_type_field="content_type")
meta_title = models.CharField(_(u"Meta title"), blank=True, default="<name>", max_length=128)
meta_keywords = models.TextField(_(u"Meta keywords"), blank=True)
meta_description = models.TextField(_(u"Meta description"), blank=True)
related_products = models.ManyToManyField("self", verbose_name=_(u"Related products"), blank=True, null=True,
symmetrical=False, related_name="reverse_related_products")
accessories = models.ManyToManyField("Product", verbose_name=_(u"Acessories"), blank=True, null=True,
symmetrical=False, through="ProductAccessories",
related_name="reverse_accessories")
active = models.BooleanField(_(u"Active"), default=False, db_index=True)
creation_date = models.DateTimeField(_(u"Creation date"), auto_now_add=True)
# Stocks
deliverable = models.BooleanField(_(u"Deliverable"), default=True, db_index=True)
manual_delivery_time = models.BooleanField(_(u"Manual delivery time"), default=False)
delivery_time = models.ForeignKey("DeliveryTime", verbose_name=_(u"Delivery time"), blank=True, null=True,
related_name="products_delivery_time")
order_time = models.ForeignKey("DeliveryTime", verbose_name=_(u"Order time"), blank=True, null=True,
related_name="products_order_time")
ordered_at = models.DateField(_(u"Ordered at"), blank=True, null=True)
manage_stock_amount = models.BooleanField(_(u"Manage stock amount"), default=False, db_index=True)
stock_amount = models.FloatField(_(u"Stock amount"), default=0, db_index=True)
active_packing_unit = models.BooleanField(_(u"Active packing unit"), default=False)
packing_unit = models.FloatField(_(u"Packing unit"), blank=True, null=True)
packing_unit_unit = models.CharField(_(u"Unit"), blank=True, max_length=30)
# Dimension # TODO : Decide if we could implement them as properties
weight = models.FloatField(_(u"Weight"), default=0.0)
height = models.FloatField(_(u"Height"), default=0.0)
length = models.FloatField(_(u"Length"), default=0.0)
width = models.FloatField(_(u"Width"), default=0.0)
# Standard Products
tax = models.ForeignKey(Tax, verbose_name=_(u"Tax"), blank=True, null=True)
# Variants
variant_group_id = models.IntegerField(_(u"Variant Group"), blank=True, null=True, db_index=True)
# Template to render product with
template = models.CharField(_("Product template path"), blank=True, null=True, max_length=256)
# others
no_index_tag = models.BooleanField(_("No index"), default=False)
supplier_has = models.BooleanField(_("Supplier has it"), default=False, db_index=True)
vendor_name = models.CharField(_(u"Vendor name"), max_length=140, blank=True)
# Manufacturer # TODO : DECIDE : if we could use this field instead of next two fields?
sku_manufacturer = models.CharField(blank=True, max_length=100)
# price aggregators functions
hotline_sku = models.CharField(_(u"hotline.ua SKU"), max_length=140, blank=True, null=True)
yandex_sku = models.CharField(_(u"Yandex.Market SKU"), max_length=128, blank=True, null=True)
objects = ProductManager()
uid = models.CharField(max_length=50)
class Meta:
ordering = ("name", )
def __unicode__(self):
return "%s (%s)" % (self.name, self.slug)
def save(self, **kwargs):
"""Overwritten to save effective_price
use.
""" # TODO : move this logic to pricelist app with effective_price stoed in session or cache
self.effective_price = self.price
super(Product, self).save(**kwargs)
def get_absolute_url(self):
"""Returns the absolute url of the product. """
return reverse('lfs_product', kwargs={"slug": self.slug}, current_app='lfs.catalog')
@property
def content_type(self):
"""Returns the content type of the product as lower string.
"""
return u"product"
def decrease_stock_amount(self, amount):
"""If the stock amount is managed by LFS, it decreases stock amount by
given amount.
"""
if self.manage_stock_amount:
self.stock_amount -= amount
self.save()
def get_accessories(self):
"""Returns the ProductAccessories relationship objects - not the
accessory (Product) objects.
This is necessary to have also the default quantity of the relationship.
"""
cache_key = self.cache_register_key("product:{0.id}:accessories")
accessories = cache.get(cache_key)
if accessories is None:
accessories = ProductAccessories.objects.select_related('accesory', 'product').filter(product=self)
accessories = accessories.filter(accessory__active=True).order_by('position')
cache.set(cache_key, accessories)
return accessories
def has_accessories(self):
"""Returns True if the product has accessories.
"""
return len(self.get_accessories()) > 0
def get_accessories_to(self):
"""Returns the Product objects which relate this product as accessory.
"""
cache_key = self.cache_register_key("product:{0.id}:accessories_to")
accessories_to = cache.get(cache_key)
if accessories_to is None:
accessories_to = ProductAccessories.objects.select_related('accessory', 'product')
accessories_to = accessories_to.filter(product__active=True).filter(accessory=self)
cache.set(cache_key, accessories_to)
return accessories_to
def get_categories(self, with_parents=False, include_system=False):
"""Returns the categories of the product.
"""
cache_key = self.cache_register_key("product-categories-{0.id}-%s-%s" % (with_parents, include_system))
categories = cache.get(cache_key)
if categories is not None:
return categories
if with_parents:
categories = []
categs = self.categories.all().order_by('position')
if not include_system:
categs = categs.exclude(is_system=True)
for category in categs:
while category:
categories.append(category)
category = category.parent
categories = categories
else:
categories = self.categories.all().order_by('position')
if not include_system:
categories = categories.exclude(is_system=True)
cache.set(cache_key, categories)
return categories
def get_category(self, root_category=None, include_system=False):
"""Returns the first category of a product.
"""
root_cat_id = root_category and root_category.id or None
cache_key = self.cache_register_key("product-category-{0.id}-%s-%s" % (root_cat_id, include_system))
category = cache.get(cache_key, False)
if category is False:
category = None
try:
if root_category:
cat_tree = map(attrgetter('id'), root_category.get_all_children(include_system=include_system))
cat_tree.append(root_category.id)
category = self.categories.filter(id__in=cat_tree)[0]
else:
category = self.get_categories(include_system=include_system)[0]
except IndexError:
category = None
cache.set(cache_key, category)
return category
def get_description(self):
""" Returns description
"""
if self.description :
return self.description
else:
return u_(u"No description")
def get_short_description(self):
"""Returns the short description of the product.
"""
if self.short_description :
return self.short_description
else:
return u_(u"No description")
def get_technical_description(self):
"""Returns the technical description from PropertyValue.
"""
res = ''
props = lfs.properties.utils.get_properties_for_product(None, self)
res = " / ".join((": ".join((prop.title, prop.value)) for prop in props))
return res or u_(u"No technical description")
def get_main_image(self):
cache_key = self.cache_register_key('product-main-image-{0.id}')
img = cache.get(cache_key)
if img is None:
img = self.images.all().order_by('position')
img = len(img) and img[0] or None
cache.set(cache_key, img)
return img and img.image or None
def get_image(self):
"""Returns the first image (the catalog image) of the product.
"""
cache_key = self.cache_register_key('product-catalog-image-{0.id}')
img = cache.get(cache_key)
if img is None:
img = self.images.filter(position__gt=-2).order_by('position')
img = len(img) and img[0] or None
cache.set(cache_key, img)
return img and img.image or None
def get_images(self):
"""Returns all images of the product, including the main image.
"""
cache_key = self.cache_register_key("product-images-{0.id}")
images = cache.get(cache_key)
if images is None:
images = self.images.all().order_by('position')
cache.set(cache_key, images)
return images
def get_sub_images(self, limit=None):
"""Returns all images of the product, except the main image.
"""
return self.get_images()[1:limit]
def get_name(self):
"""Returns the name of the product.
"""
return self.name
def get_sku(self):
"""Returns the sku of the product.
"""
return self.sku
def get_tax_rate(self):
"""Returns the tax rate of the product.
"""
cache_key = self.cache_register_key("tax-rate-for-product-{0.id}")
tax_rate = cache.get(cache_key)
if tax_rate is None:
if self.tax_id:
tax_rate = Tax.get_by_id(None, self.tax_id).rate # because of extra hit to db to get tax
else:
tax_rate = 0.0
cache.set(cache_key, tax_rate)
return tax_rate
def has_related_products(self):
"""Returns True if the product has related products.
"""
cache_key = self.cache_register_key("has-related-products-{0.id}")
related_products = cache.get(cache_key)
if related_products is None:
related_products = self.related_products.all().exists()
cache.set(cache_key, related_products)
return related_products
def has_variants(self):
"""WRITE!!!!
"""
cache_key = self.cache_register_key("has-variants-{0.id}")
result = cache.get(cache_key)
if result is None:
qs = Product.objects.filter(variant_group_id=self.variant_group_id)
qs = qs.exclude(pk = self.pk)
if self.variant_group_id and qs.exists():
result = True
else:
result = False
cache.set(cache_key, result)
return result
def get_variants(self):
"""WRITE!!!!
"""
cache_key = self.cache_register_key("get-variants-{0.id}")
result = cache.get(cache_key)
if result is None:
qs = Product.objects.filter(variant_group_id=self.variant_group_id)
qs = qs.exclude(pk = self.pk)
result = qs
cache.set(cache_key, result)
return result
def get_related_products(self):
"""Returns the related products of the product.
"""
cache_key = self.cache_register_key("related-products-{0.id}")
related_products = cache.get(cache_key)
if related_products is None:
related_products = self.related_products.all()
cache.set(cache_key, related_products)
return related_products
# Dimensions
def get_weight(self):
"""Returns weight of the product.
"""
return self.weight
def get_width(self):
"""Returns width of the product.
"""
return self.width
def get_length(self):
"""Returns length of the product.
"""
return self.length
def get_height(self):
"""Returns height of the product.
"""
return self.height
def get_packing_info(self):
"""Returns the packing info of the product as list:
"""
return (self.packing_unit, self.packing_unit_unit)
def is_active(self):
"""Returns the activity state of the product.
"""
return self.active
def is_deliverable(self, request=None):
"""Returns the deliverable state of the product.
"""
if not self.is_available(request=request):
return False
return self.deliverable
# 3rd party contracts
def get_parent_for_portlets(self):
"""Returns the current category. This will add the portlets of the
current category to the product portlets.
"""
return self.get_category()
def get_template_name(self):
"""
method to return the path of the product template
"""
return self.template or None
def is_available(self, qty=0, request=None):
"""
checks product_availability.
if product has price less or equal to 0
or ( manage_stock_amount is true but stock_amount less than qty)
then product is not available and this method will return False.
If product is available then returned value is True
"""
from lfs.pricelist.utils import get_default_price
if qty == 0: # this need for copatability with pricelists api
qty = 1
if self.manage_stock_amount and self.get_stock_amount() < qty and not self.supplier_has:
return False
return bool(get_default_price(request, self) > 0)
def get_videos(self):
"""Returns the video objects for this product.
"""
cache_key = self.cache_register_key("product:{0.id}:videos")
videos = cache.get(cache_key)
if videos is None:
videos = Video.objects.filter(product=self)
cache.set(cache_key, videos)
return videos
def get_discounts(self):
"""Returns list of discount sets which has given product.
"""
cache_key = self.cache_register_key("product:{0.id}:discounts")
discounts = cache.get(cache_key)
if discounts is None:
discounts = DiscountSet.objects.filter(products=self)
try:
cache.set(cache_key, discounts, settings.CACHE_TIMEOUT_PRICES)
except AttributeError:
cache.set(cache_key, discounts)
return discounts
def get_files(self):
"""Returns all files for this product.
"""
cache_key = self.cache_register_key("product:{0.id}:files")
files = cache.get(cache_key)
if files is None:
ctype = ContentType.objects.get(model='product')
files = File.objects.filter(content_type=ctype, content_id=self.id).order_by('position')
cache.set(cache_key, files)
return files
def get_stock_amount(self):
""" Returns the remainder of the products in stock with movement
If amount < 0 then return 0
@return: int
"""
return Product.objects.product_info(self)['stock_amount']
Sorry for the boring and long code - but it's comprehensive information! 😃
from django-autofixture.
Cool, thanks for the quick reply. Do you know what's the field that is causing this issue? Is the related_products
referencing self
?
Maybe this will take me on the path of finding the issue.
from django-autofixture.
So, I changed method a little:
def process_m2m(self, instance, field):
# check django's version number to determine how intermediary models
# are checked if they are auto created or not.
auto_created_through_model = False
try:
through = field.rel.through
auto_created_through_model = through._meta.auto_created
except:
print "Exception %s" % field
auto_created_through_model = None
if auto_created_through_model:
return self.process_field(instance, field)
and run it..
(venv)melihoff@melihoff-pc:~/sites/iplaza$ ./manage.py loadtestdata --traceback catalog.Product:10
Exception <django.contrib.contenttypes.generic.GenericRelation: images>
So, trouble with field
images = generic.GenericRelation("Image", verbose_name=_(u"Images"),
object_id_field="content_id", content_type_field="content_type")
I hope it helps. But I stuck with speed - with default attr commit=True in create method it works too slow. I need to create 100000+ products and it takes long long time 😢 So I trying to set commit=False, and change logic to
for model, count in models:
# if use:
# fixture = use(model, **kwargs)
# fixture.create(count)
# else:
instances = autofixture.create(model, count, **kwargs)
model.objects.bulk_create(instances)
print "model %s DONE" % model
Now its runs 2X better, but it fails if count > 10000 (abt) with memory problems
from django-autofixture.
Image class:
class Image(CacheInvalidatorMixin, models.Model):
"""An image with a title and several sizes. Can be part of a product or
category.
Attributes:
- content
The content object it belongs to.
- title
The title of the image.
- image
The image file.
- position
The position of the image within the content object it belongs to.
"""
content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), related_name="image", db_index=True,
blank=True, null=True)
content_id = models.PositiveIntegerField(_(u"Content id"), blank=True, null=True, db_index=True)
content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id")
title = models.CharField(_(u"Title"), blank=True, max_length=100)
image = ImageWithThumbsField(_(u"Image"), upload_to="images", blank=True, null=True, sizes=PRODUCT_IMAGE_SIZES)
position = models.SmallIntegerField(_(u"Position"), default=999, db_index=True)
# Cache Invalidator Parametrs
_invalidate_fk_fields = ['content']
class Meta:
ordering = ("position", )
def __unicode__(self):
return self.title
from django-autofixture.
I recently ran into this same issue and it appears that the AttributeError: 'NoneType' object has no attribute '_meta'
issue arises when a model has both TaggableManager
AND GenericForeignKey
attributes.
from django-autofixture.
Related Issues (20)
- Better support for choices, null=True and blank=True
- Integration with Faker
- Support for Django 2.0 HOT 9
- Error with Django 2: TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. HOT 3
- How to populate a reverse relationship?
- Use of bulk_create
- Allow muting signals in a way similar to factoryboy HOT 1
- Raise an error in case when field doesn't exist in a model.
- django.utils.six -> six in latest version of django HOT 2
- python setup.py egg_info did not run successfully HOT 6
- Unknown command: 'loadtestdata' Type 'manage.py help' for usage. HOT 3
- docs could be a bit easier to follow for newer developer HOT 1
- Frequently got ``TransactionManagementError`` HOT 6
- could we add Point fields into django-autofixture ? HOT 4
- errro with mysql Row size HOT 1
- Recursive generate_fx HOT 1
- Add max length value
- Ability to add default photos from custom folder path HOT 3
- How to generate random value from given list? HOT 1
- Support for Django 1.10 and higher? HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-autofixture.