django-import-export : import not working - python

I am trying to populate my database with .csv files with django-import-export module but I keep running in this error
Line number: 1 - maximum recursion depth exceeded while calling a Python object 43, Sicilian, L, 0, 1,7, 45.7
whenever I try to populate my Pizza model through the admin UI.
Here is my CSV
admin.py
from django.contrib.admin import ModelAdmin
from import_export.admin import ImportExportModelAdmin
from .models import Topping, Pizza, Sub, Pasta, Salad, Dinner
class PizzaAdmin(ImportExportModelAdmin):
def save_related(self, request, form, formsets, change):
super(PizzaAdmin, self).save_related(request, form, formsets, change)
form.instance.toppings.add(Topping.objects.get(name='Cheese'))
#admin.register(Sub)
class SubAdmin(ImportExportModelAdmin):
pass
# Register your models here.
admin.site.register(Topping)
admin.site.register(Pizza, PizzaAdmin)
# admin.site.register(Sub)
admin.site.register(Pasta)
admin.site.register(Salad)
admin.site.register(Dinner)
models.py
from django.contrib import admin
from django.db import models
from django.contrib.auth.models import User
from django.dispatch import receiver
from django.db.models.signals import post_save
from django.core.validators import MinValueValidator, MaxValueValidator
from django.contrib.auth import get_user_model
# Create your models here.
class Topping(models.Model):
name = models.CharField(max_length=64)
def __str__(self):
return(f"{self.name}")
class Pizza(models.Model):
PIZZA_SIZES = (
('S', 'Small'),
('L', 'Large'),
)
pizza_type = models.CharField(max_length=64)
pizza_size = models.CharField(max_length=1, choices=PIZZA_SIZES)
qty_toppings = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(3)], default=0)
toppings = models.ManyToManyField(Topping, related_name='pizzas', blank=True)
price = models.FloatField(help_text="Price in $")
def __str__(self):
return f"Size: {self.get_pizza_size_display()}, Type: {self.pizza_type}, Number of Toppings: {self.qty_toppings}, Price: {self.price}, Toppings: {self.toppings.in_bulk()}"
def save(self, *args, **kwargs):
# if 'toppings' not in kwargs:
# kwargs.setdefault('force_insert', True)
# kwargs.setdefault('force_update', True)
super(Pizza, self).save(*args, **kwargs)
self.toppings.add(Topping.objects.get(name='Cheese'))
# kwargs.setdefault('toppings', Topping.objects.get(name='Cheese'))
class Sub(models.Model):
SUBS_SIZES = (
('S', 'Small'),
('L', 'Large'),
)
subs_size = models.CharField(max_length=1, choices=SUBS_SIZES)
name = models.CharField(max_length=64)
price = models.IntegerField(help_text="Price in $")
def __str__(self):
return f"{self.name}, {self.get_subs_size_display()} : {self.price}"
class Pasta(models.Model):
name = models.CharField(max_length=64)
price = models.IntegerField(help_text="Price in $")
def __str__(self):
return f"{self.name} : {self.price}"
class Salad(models.Model):
name = models.CharField(max_length=64)
price = models.IntegerField(help_text="Price in $")
def __str__(self):
return f"{self.name} : {self.price}"
class Dinner(models.Model):
DINNER_SIZES = (
('S', 'Small'),
('L', 'Large'),
)
dinner_size = models.CharField(max_length=1, choices=DINNER_SIZES)
name = models.CharField(max_length=64)
price = models.IntegerField(help_text="Price in $")
def __str__(self):
return f"{self.name}, {self.get_dinner_size_display()} : {self.price}"
class Euser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
return(f"{self.id}")
class ShoppingCart(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
pizzas = models.ManyToManyField(Pizza)
subs = models.ManyToManyField(Sub)
pastas = models.ManyToManyField(Pasta)
dinners = models.ManyToManyField(Dinner)
number_of_articles = models.IntegerField(null=True)
price = models.DecimalField(max_digits=5, decimal_places=2, null=True)
def __str__(self):
return(f"{self.user}'s cart")
#receiver(post_save, sender=get_user_model())
def create_user_cart(sender, instance, created, **kwargs):
if created:
ShoppingCart.objects.create(user=instance)
# #receiver(post_save, sender=User)
# def create_user_cart(sender, instance, created, **kwargs):
# if created:
# ShoppingCart.objects.create(user=instance)
# #receiver(post_save, sender=User)
# def save_user_cart(sender, instance, **kwargs):
# instance.shoppingcart.save()
FYI: Used pandas to convert this same .csv to a .json, and I got KeyError encountered while trying to read file: pizza_sicilian.json
Any help will be greatly appreciated

i have faced the same issue
i would rather suggest you
in admin .py
#admin.register(Sub)
class SubAdmin(ImportExportModelAdmin):
list_display=["pizza","other objects in model"]
pass
list_display is a default function an the items should be in a list ...
this solved my issue , i think it will help many viewers!
Thnak you!

Related

How to render choices in a Django field based on a condition

I have a custom user model:
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
is_worker = models.BooleanField(default=False)
is_customer = models.BooleanField(default=True)
def __str__(self):
return f'{self.username} - {self.is_worker}'
And I have this model services :
from django.db import models
from users.models import CustomUser
SERVICE_CHOICES = (
('Carpenter', 'Carpenter'),
('Driver', 'Driver'),
('Ambulanve', 'Ambulanve'),
('Spa', 'Spa'),
('Barber', 'Barber'),
('Cleaning', 'Cleaning'),
('Cook', 'Cook'),
)
class Service(models.Model):
name = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
service = models.CharField(choices=SERVICE_CHOICES,max_length=100)
def __str__(self):
return f'{self.service} - {self.name}'
In services model, I am using CustomUser model for the name. Whereas, I need only those names where is_worker = True. In my code, I am getting all the users irrespective of the status. How can I change it?
You can use ForeignKey.limit_choices_to to set a limit of available choices for a foreignkey field. In your case :
class Service(models.Model):
name = models.ForeignKey(CustomUser, on_delete=models.CASCADE, limit_choices_to={'is_worker': True},)
service = models.CharField(choices=SERVICE_CHOICES,max_length=100)
def __str__(self):
return f'{self.service} - {self.name}'
Django doc
something like that:
class ServiceForm(ModelForm):
def __init__(
self,
*args,
**kwargs
):
super().__init__(*args, **kwargs)
if self.instance and self.instance.is_worker:
self.fields['service'].widget = forms.Select(
choices=[(k, v)
for i in SERVICE_CHOICES if v in ('Barber', 'Spa')]
)

django ecommerce product db design

I designed a database for my django ecommerce project but it have some problems, the goal of
the this design is to have products with different specifications for example a mobile cell has it's own properties and a television too,
it is my models.py:
'''
from django.db import models
from mptt.models import MPTTModel, TreeForeignKey
from django.shortcuts import reverse
from model_utils import FieldTracker
from . import uploaders
class Category(MPTTModel):
name = models.CharField(max_length=50, unique=True)
parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True,
related_name='children')
slug = models.SlugField(max_length=75, unique=True)
tracker = FieldTracker(fields=['name'])
class MPTTMeta:
order_insertion_by = ['name']
def __str__(self):
category_names = [self.name]
node = self
while node.parent:
node = node.parent
category_names.append(node.name)
return ' / '.join(category_names[::-1])
def get_absolute_url(self):
return reverse('product_by_category', args=(self.slug,))
class ProductType(models.Model):
name = models.CharField(max_length=50, unique=True)
def __str__(self):
return self.name
class ProductSpecifications(models.Model):
name = models.CharField(max_length=50)
product_type = models.ForeignKey(ProductType, on_delete=models.CASCADE,
related_name='specifications')
class Meta:
unique_together = ('name', 'product_type')
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=100, unique=True)
product_type = models.ForeignKey(ProductType, on_delete=models.CASCADE,
related_name='products')
category = models.ForeignKey(Category, on_delete=models.CASCADE,
related_name='products')
price = models.PositiveBigIntegerField()
discount_price = models.PositiveBigIntegerField(null=True, blank=True)
description = models.TextField(null=True, blank=True)
image = models.ImageField(upload_to=uploaders.product_img_uploader)
slug = models.SlugField(max_length=150, unique=True)
tracker = FieldTracker(fields=['slug', 'name', 'product_type'])
def __str__(self):
return self.name
def set_discount(self, percentage):
self.discount_price = self.price * (1 - percentage)
self.save()
#property
def is_discounted(self):
return bool(self.discount_price)
def remove_discount(self):
self.discount_price = None
self.save()
class ProductSpecificationValue(models.Model):
specification = models.ForeignKey(ProductSpecifications, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE,
related_name='specifications')
value = models.CharField(max_length=75, null=True, blank=True)
def __str__(self):
return ''
class Meta:
unique_together = ('specification', 'product')
'''
And admin.py:
'''
from django.contrib import admin
from django.http import HttpResponseRedirect
from mptt.admin import MPTTModelAdmin
from .models import *
from .forms import ProductSpecForm
#admin.register(Category)
class CategoryAdmin(MPTTModelAdmin):
readonly_fields = ('slug',)
class SpecificationInline(admin.TabularInline):
model = ProductSpecifications
extra = 2
#admin.register(ProductType)
class ProductTypeAdmin(admin.ModelAdmin):
inlines = (SpecificationInline,)
class SpecificationValueInline(admin.TabularInline):
model = ProductSpecificationValue
# form = ProductSpecForm
# fields = ('specification', 'value')
# readonly_fields = ('specification',)
#
# def has_add_permission(self, request, obj):
# return False
#
# def has_delete_permission(self, request, obj=None):
# return False
#admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
inlines = (SpecificationValueInline,)
readonly_fields = ('slug',)
# def response_post_save_add(self, request, obj):
# return HttpResponseRedirect(
# reverse("admin:%s_%s_change" % (self.model._meta.app_label,
# self.model._meta.model_name), args=(obj.id,)))
'''
the problem is in product admin panel when you want to add or change a product, I want the select box for specification in SpecificationValueInline form show me only specifications related to the product type not all specifications in db, the lines that I commented in admin.py with some signals and a form was my approach to solve this issue i dont know if it was the best help me please!
signals.py:
'''
from django.dispatch import receiver
from django.db.models.signals import pre_save, post_save
from .models import Category, Product, ProductSpecificationValue, ProductSpecifications
#receiver(pre_save, sender=Product)
#receiver(pre_save, sender=Category)
def initialize_slug(sender, instance, *args, **kwargs):
if (not instance.slug) or (instance.tracker.has_changed('name')):
instance.slug = instance.name.replace(' ', '_')
#receiver(post_save, sender=Product)
def initialize_specifications(sender, instance, created, **kwargs):
if created:
product_type = instance.product_type
for specification in product_type.specifications.all():
ProductSpecificationValue.objects.create(product=instance,
specification=specification)
elif instance.tracker.has_changed('product_type'):
ProductSpecificationValue.objects.filter(product=instance).delete()
product_type = instance.product_type
for specification in product_type.specifications.all():
ProductSpecificationValue.objects.create(product=instance,
specification=specification)
#receiver(post_save, sender=ProductSpecifications)
def add_new_specs_to_related_products(sender, instance, created, **kwargs):
if created:
product_type = instance.product_type
for product in product_type.products.all():
ProductSpecificationValue.objects.create(specification=instance,
product=product)
'''
forms.py:
'''
from django import forms
from django.forms import ModelChoiceField
from .models import ProductSpecificationValue, Product
class ProductSpecForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if hasattr(self.instance, 'product'):
self.fields['specification'] = ModelChoiceField(
queryset=self.instance.product.product_type.specifications.all())
class Meta:
model = ProductSpecificationValue
fields = ('specification', 'value')
'''
you can use formfield_for_foreignkey in SpecificationValueInline
class SpecificationValueInline(admin.TabularInline):
model = ProductSpecificationValue
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "specification":
product_id = request.resolver_match.kwargs.get('object_id')
productType = Product.objects.get(id = product_id).product_type
kwargs["queryset"] = ProductSpecification.objects.filter(product_type=productType)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
mohsen ma answer was usefull I made some changes and it got better but I still doubt it it is enough or best practice, if user changes the product type he/she should stay on change page to fill the specification idk how:
'''
#receiver(post_save, sender=Product)
def sync_specs_with_type(sender, instance, created, **kwargs):
if created or instance.tracker.has_changed('product_type'):
if not created:
instance.specifications.all().delete()
for spec in instance.product_type.specifications.all():
ProductSpecificationValue.objects.create(product=instance, specification=spec)
class SpecificationValueInline(admin.TabularInline):
model = ProductSpecificationValue
extra = 0
def formfield_for_foreignkey(self, db_field, request, **kwargs):
product_id = request.resolver_match.kwargs.get('object_id')
if product_id and db_field.name == "specification":
product_type = Product.objects.get(id=product_id).product_type
kwargs["queryset"] = ProductSpecifications.objects.filter(product_type=product_type)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
#admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
readonly_fields = ('slug',)
inlines = (SpecificationValueInline,)
def response_post_save_add(self, request, obj):
messages.add_message(request, messages.INFO, 'set you product specifications')
return HttpResponseRedirect(
reverse("admin:%s_%s_change" % (self.model._meta.app_label, self.model._meta.model_name), args=(obj.id,)))
def get_inlines(self, request, obj):
if obj:
return super().get_inlines(request, obj)
return ()
'''

Django How to add a default Variation when creating a new Item

I have created a an item model with variation and variation Manager model.
I want to add a default variation function so that when I create a new item a default of size variations is created small medium and large.
I edited the question by adding a Signal but getting an error so I trying to reach somewhere now I'm getting name 'created' is not defined
Here is the model:
class Item(models.Model):
title = models.CharField(max_length=100)
price = models.DecimalField(decimal_places=2, max_digits=100)
category = models.CharField(choices=CATEGORY_CHOICES, max_length=2)
label = models.CharField(choices=LABEL_CHOICES, max_length=1)
slug = models.SlugField(unique=True)
image = models.ImageField(blank=False, upload_to='')
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
active = models.BooleanField(default=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("core:product", kwargs={
'slug': self.slug
})
class VariationManager(models.Manager):
def all(self):
return super(VariationManager, self).filter(active=True)
def sizes(self):
return self.all().filter(category='size')
def colors(self):
return self.all().filter(category='color')
VAR_CATEGORIES = (
('size', 'size',),
('color', 'color',),
('package', 'package'),
)
class Variation(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
category = models.CharField(
max_length=120, choices=VAR_CATEGORIES, default='size')
title = models.CharField(max_length=120)
price = models.DecimalField(
decimal_places=2, max_digits=100, null=True, blank=True)
objects = VariationManager()
active = models.BooleanField(default=True)
def __str__(self):
return self.title
#receiver(post_save, sender=Item)
def add_default_Variant(sender, instance, **kwargs):
small_size, size = Variation.objects.get_or_create(
title='Small', item=instance)
medium_size, size = Variation.objects.get_or_create(
title='Medium', item=instance)
large_size, size = Variation.objects.get_or_create(
title='Large', item=instance)
if created:
instance.save()
print(f"default variant created : {variant}")
you can use signals to add what you want DOCS
from django.db.models.signals import post_save
from django.dispatch import receiver
this signal will create a new variant each time you save a new item
you can put in models.py or follow the docs to set it in a separated .py file
#receiver(post_save, sender=Item)
def add_default_Variant(sender, instance, **kwargs):
variant= Variation.objects.create(title="default variant title",item=instance)
Adding your variants
from django.db.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=Item)
def add_default_Variant(sender, instance, **kwargs):
small_size = Variation.objects.create(product=instance, category='size', title='Small')
medium_size = Variation.objects.create(product=instance, category='size', title='Medium')
large_size = Variation.objects.create(product=instance, category='size', title='Large')

bypass validation for form field django

class PostForm(forms.ModelForm):
description = forms.CharField(widget=PagedownWidget(show_preview=False))
class Meta:
model = Post
fields = [
'title',
'image',
'video',
'description',
'public',
'tags',
]
I am trying to bypass the required field for 'video' but having difficulty doing so. Any suggestions would be appreciated.
this is my models.py, hopefully is should help with knowing how to go on this.
from django.db import models
from django.db.models import Count, QuerySet, F
from django.utils import timezone
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse
from django.db.models.signals import pre_save
from django.utils.text import slugify
from markdown_deux import markdown
from django.utils.safestring import mark_safe
from embed_video.fields import EmbedVideoField
from taggit.managers import TaggableManager
from comments.models import Comment
def upload_location(instance, filename):
return "%s/%s" %(instance.slug, filename)
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1 )
title = models.CharField(max_length=75)
slug = models.SlugField(unique=True)
video = EmbedVideoField()
image = models.ImageField(
upload_to=upload_location,
null=True,
blank=True,
width_field="width_field",
height_field="height_field")
height_field = models.IntegerField(default=0)
width_field = models.IntegerField(default=0)
description = models.TextField()
tags = TaggableManager()
public = models.BooleanField(default=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
created = models.DateTimeField(auto_now_add=True, auto_now=False)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"slug": self.slug})
class Meta:
ordering = ["-created", "-updated" ]
def get_markdown(self):
description = self.description
markdown_text = markdown(description)
return mark_safe(markdown_text)
#property
def comments(self):
instance = self
qs = Comment.objects.filter_by_instance(instance)
return qs
#property
def get_content_type(self):
instance = self
content_type = ContentType.objects.get_for_model(instance.__class__)
return content_type
def create_slug(instance, new_slug=None):
slug = slugify(instance.title)
if new_slug is not None:
slug = new_slug
qs = Post.objects.filter(slug=slug).order_by("-id")
exists = qs.exists()
if exists:
new_slug = "%s-%s" %(slug, qs.first().id)
return create_slug(instance, new_slug=new_slug)
return slug
def pre_save_post_receiver(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = create_slug(instance)
pre_save.connect(pre_save_post_receiver, sender=Post)
from the docs it looks like it should support empty now since version 0.3, i would suggest trying
video = EmbedVideoField(null=True,blank=True)
the docs say it should function like a URL field, so just the standard notation should be all you need.
good luck!

Import error in Django models on importing from another app

I'm having an app called project with the following models.py file (the hastags are put in the code for purpose, so as to nullify the lines of codes)
#inside project.models.py
from django.db import models
# Create your models here.
from django.db.models import signals
from django.core.urlresolvers import reverse
from django.template.defaultfilters import slugify
from django.utils import timezone
from datetime import datetime
import datetime as dt
from crm.models import Project
#from warehouse.models import Warehouse (hastagged for reason)
class UnitItem(models.Model):
unitname=models.CharField(max_length = 10, unique=True)
symbol=models.CharField(max_length=10, unique=True)
slug=models.SlugField(max_length=300)
def save(self, *args, **kwargs):
if not self.id:
self.slug=slugify(self.unitname)
super(UnitItem, self).save(*args, **kwargs)
def __str__(self):
return self.unitname
class BOQItem(models.Model):
project=models.ForeignKey(Project,related_name='boq_project_crm_project')
slug=models.SlugField(max_length=300)
code=models.CharField(max_length=300, unique=True)
detail=models.CharField(max_length=300, unique=True)
unit_name=models.ForeignKey(UnitItem, to_field ='unitname', related_name='boq_project_project_unit')
quantity=models.DecimalField(max_digits=12, decimal_places=4)
purchase_rate=models.DecimalField(max_digits=12, decimal_places=2)
sales_rate=models.DecimalField(max_digits=12, decimal_places=2)
freight_insurance_rate=models.DecimalField(max_digits=12, decimal_places=2)
def save(self, *args, **kwargs):
if not self.id:
self.slug=slugify(self.code)
super(BOQItem, self).save(*args, **kwargs)
def __str__(self):
return '%s %s' % (self.code, self.detail)
#For Material Request
class EMRItem(models.Model):
emr_id=models.CharField(max_length=50, unique=True)
slug=models.SlugField(max_length=300)
project=models.ForeignKey(Project,related_name='emr_project_crm_project')
created_on=models.DateTimeField(null=True, blank=True)
edited_on=models.DateTimeField(null=True, blank=True)
#warehouse=models.ForeignKey(Warehouse,related_name='emr_project_warehouse_warehouse')
def save(self, *args, **kwargs):
data="emr"
today=dt.date.today()
today_string=today.strftime('%y%m%d')
next_emr_number='001'
last_emr=type(self).objects.filter(emr_id__startswith=today_string).order_by('emr_id').last()
if last_emr:
last_emr_number=int(last_emr.emr_id[6:])
next_emr_number='{0:03d}'.format(last_emr_number + 1)
self.emr_id=data + today_string + next_emr_number
if not self.id:
self.slug=slugify(self.emr_id)
self.created_on=timezone.now()
else:
self.edited_on=timezone.now()
super(EMRItem, self).save(*args, **kwargs)
def __str__(self):
return '%s %s %s' % (self.emr_id, self.project, self.date)
class EMRLineItem(models.Model):
emr_no=models.ForeignKey(EMRItem, related_name='emrline_project_project_emr')
item=models.ForeignKey(BOQItem,
related_name='emrline_project_project_boqitem')
suggest_rate=models.DecimalField(max_digits=12, decimal_places=2)
unit_name=models.ForeignKey(UnitItem, to_field ='unitname', related_name='emrline_project_project_unit')
quantity=models.DecimalField(max_digits=12, decimal_places=4)
#For Purchase Order
class POItem(models.Model):
po_id=models.CharField(max_length=50, unique=True)
slug=models.SlugField(max_length=300)
project=models.ForeignKey(Project,related_name='po_project_crm_project')
created_on=models.DateTimeField(null=True, blank=True)
edited_on=models.DateTimeField(null=True, blank=True)
#warehouse=models.ForeignKey(Warehouse,related_name='po_project_warehouse_warehouse')
def save(self, *args, **kwargs):
data="po"
today=dt.date.today()
today_string=today.strftime('%y%m%d')
next_po_number='001'
last_po=type(self).objects.filter(po_id__startswith=today_string).order_by('po_id').last()
if last_po:
last_po_number=int(last_po.po_id[6:])
next_po_number='{0:03d}'.format(last_po_number + 1)
self.po_id=data + today_string + next_po_number
if not self.id:
self.slug=slugify(self.po_id)
self.created_on=timezone.now()
else:
self.edited_on=timezone.now()
super(POItem, self).save(*args, **kwargs)
def __str__(self):
return '%s %s %s' % (self.po_id, self.project, self.date)
class POLineItem(models.Model):
po_no=models.ForeignKey(POItem, related_name='poline_project_project_po')
item=models.ForeignKey(BOQItem, related_name='poline_project_project_boqitem')
purchase_rate=models.DecimalField(max_digits=12, decimal_places=2)
unit_name=models.ForeignKey(UnitItem, to_field ='unitname', related_name='poline_project_project_unit')
quantity=models.DecimalField(max_digits=12, decimal_places=4)
class Indent(models.Model):
indent_id=models.CharField(max_length=50, unique=True)
slug=models.SlugField(max_length=300)
project=models.ForeignKey(Project, related_name='indent_project_crm_project')
created_on=models.DateTimeField(null=True, blank=True)
edited_on=models.DateTimeField(null=True, blank=True)
#warehouse=models.ForeignKey(Warehouse,related_name='indent_project_warehouse_warehouse')
delivery_address=models.CharField(max_length=500, unique=True)
def save(self, *args, **kwargs):
data="ind"
today=dt.date.today()
today_string=today.strftime('%y%m%d')
next_indent_number='001'
last_indent=type(self).objects.filter(
indent_id__startswith=today_string)
.order_by('indent_id').last()
if last_indent:
last_indent_number=int(last_indent.indent_id[6:])
next_indent_number='{0:03d}'.format(last_indent_number + 1)
self.indent_id=data + today_string + next_indent_number
if not self.id:
self.slug=slugify(self.indent_id)
self.created_on=timezone.now()
else:
self.edited_on=timezone.now()
super(Indent, self).save(*args, **kwargs)
class IndentLineItem(models.Model):
indent_no=models.ForeignKey(Indent, related_name='indentline_project_project_indent')
item=models.ForeignKey(BOQItem, related_name='indentline_project_project_boqitem')
unit_name=models.ForeignKey(UnitItem, to_field ='unitname', related_name='indentline_project_project_unit')
quantity=models.DecimalField(max_digits=12, decimal_places=4)
class SalesInvoice(models.Model):
invoice_id=models.CharField(max_length=50, unique=True)
project=models.ForeignKey(Project, related_name='salesinvoice_project_crm_project')
dispatch_by=models.CharField(max_length=100)
lr_no=models.CharField(max_length=100, null=True, blank=True)
transportner=models.CharField(max_length=300, null=True, blank=True)
vehicle_no=models.CharField(max_length=100, null=True, blank=True)
created_on=models.DateTimeField(null=True, blank=True)
edited_on=models.DateTimeField(null=True, blank=True)
def save(self, *args, **kwargs):
data="invc"
today=dt.date.today()
today_string=today.strftime('%y%m%d')
next_invoice_number='001'
last_invoice=type(self).objects
.filter(invoice_id__startswith=today_string)
.order_by('invoice_id').last()
if last_invoice:
last_invoice_number=int(last_invoice.invoice_id[6:])
next_invoice_number='{0:03d}'.format(last_invoice_number + 1)
self.invoice_id=data + today_string + next_invoice_number
if not self.id:
self.slug=slugify(self.invoice_id)
self.created_on=timezone.now()
else:
self.edited_on=timezone.now()
super(SalesInvoice, self).save(*args, **kwargs)
class SalesLineItem(models.Model):
item=models.ForeignKey(BOQItem, related_name='salesline_project_project_boqitem')
unit_name=models.ForeignKey(UnitItem, to_field ='unitname', related_name='salesline_project_project_unit')
quantity=models.DecimalField(max_digits=12, decimal_places=4)
unit_rate=models.DecimalField(max_digits=12, decimal_places=2)
You could see in the code, I'm calling warehouse model from the Warehouse app and this seems to work fine unless the following code comes into play:
#inside warehouse.models.py
from django.db import models
# Create your models here.
from django.db.models import signals
from django.core.urlresolvers import reverse
from django.template.defaultfilters import slugify
from datetime import datetime
from crm.models import Project
#from project.models import BOQItem, SalesInvoice, UnitItem, POItem (hashed intentionally, to check if the code is working)
class Warehouse(models.Model):
code=models.CharField(max_length=100, unique=True)
address=models.CharField(max_length=500)
slug=models.SlugField(max_length=150)
#def get_absolute_url(self):
# return reverse('master_detail', kwargs={'detail':self.slug})
def save(self, *args, **kwargs):
if not self.id:
self.slug=slugify(self.code)
super(Warehouse, self).save(*args, **kwargs)
class Meta:
ordering = ('code',)
def __str__(self):
return self.code
class AbstractStock(models.Model):
quantity=models.DecimalField(max_digits=12, decimal_places=4)
address=models.CharField(max_length=500)
slug=models.SlugField(max_length=150)
class Meta:
abstract = True
class InventoryStock(AbstractStock):
warehouse=models.ForeignKey(Warehouse, related_name='inventorystock_warehouse_warehouse_warehouse')
project=models.ForeignKey(Project, related_name='inventorystock_warehouse_crm_project')
# inventory=models.ForeignKey(BOQItem,related_name='inventorystock_warehouse_project_boq')
#def get_absolute_url(self):
# return reverse('master_detail', kwargs={'detail':self.slug})
def save(self, *args, **kwargs):
if not self.id:
self.slug=slugify(self.code)
super(Warehouse, self).save(*args, **kwargs)
def __str__(self):
return '%s %s' % (self.inventory.code, self.inventory.detail)
class WIPStock(AbstractStock):
warehouse=models.ForeignKey(Warehouse, related_name='wipstock_warehouse_warehouse_warehouse')
project=models.ForeignKey(Project, related_name='wipstock_warehouse_crm_project')
# inventory=models.ForeignKey(BOQItem,related_name='wipstock_warehouse_project_boq')
#def get_absolute_url(self):
# return reverse('master_detail', kwargs={'detail':self.slug})
def save(self, *args, **kwargs):
if not self.id:
self.slug=slugify(self.code)
super(Warehouse, self).save(*args, **kwargs)
def __str__(self):
return '%s %s' % (self.inventory.code, self.inventory.detail)
class MRN(models.Model):
mrn_id=models.CharField(max_length=50, unique=True)
project=models.ForeignKey(Project, related_name='mrn_warehouse_crm_project')
# invoice_id=models.ForeignKey(POItem,related_name='mrn_warehouse_project_po')
created_on=models.DateTimeField(null=True, blank=True)
edited_on=models.DateTimeField(null=True, blank=True)
def save(self, *args, **kwargs):
data="mrn"
today=dt.date.today()
today_string=today.strftime('%y%m%d')
next_mrn_number='001'
last_mrn=type(self).objects.filter(mrn_id__startswith=today_string)
.order_by('mrn_id').last()
if last_mrn:
last_mrn_number=int(last_mrn.mrn_id[6:])
next_mrn_number='{0:03d}'.format(last_mrn_number + 1)
self.mrn_id=data + today_string + next_mrn_number
if not self.id:
self.slug=slugify(self.mrn_id)
self.created_on=timezone.now()
else:
self.edited_on=timezone.now()
super(MRN, self).save(*args, **kwargs)
def __str__(self):
return self.mrn_id
class MRNLineItem(models.Model):
# item=models.ForeignKey(BOQItem,related_name='mrnline_warehouse_project_boqitem')
#unit_name=models.ForeignKey(UnitItem, to_field ='unitname', related_name='mrnline_warehouse_project_unit')
quantity=models.DecimalField(max_digits=12, decimal_places=4)
purchase_rate=models.DecimalField(max_digits=12, decimal_places=2)
class DeliveryChallan(models.Model):
dc_id=models.CharField(max_length=50, unique=True)
project=models.ForeignKey(Project, related_name='deliverychallan_warehouse_crm_project')
#invoice_id=models.ForeignKey(SalesInvoice,related_name='deliverychallan_warehouse_project_salesinvoice')
created_on=models.DateTimeField(null=True, blank=True)
edited_on=models.DateTimeField(null=True, blank=True)
warehouse=models.ForeignKey(Warehouse, related_name='deliverychallan_warehouse_warehouse_warehouse')
def save(self, *args, **kwargs):
data="dc"
today=dt.date.today()
today_string=today.strftime('%y%m%d')
next_dc_number='001'
last_dc=type(self).objects.filter(dc_id__startswith=today_string)
.order_by('dc_id').last()
if last_dc:
last_dc_number=int(last_dc.dc_id[6:])
next_dc_number='{0:03d}'.format(last_dc_number + 1)
self.dc_id=data + today_string + next_dc_number
if not self.id:
self.slug=slugify(self.dc_id)
self.created_on=timezone.now()
else:
self.edited_on=timezone.now()
super(DeliveryChallan, self).save(*args, **kwargs)
def __str__(self):
return self.dc_id
class DCLineItem(models.Model):
#item=models.ForeignKey(BOQItem, related_name='dcline_warehouse_project_boqitem')
#unit_name=models.ForeignKey(UnitItem, to_field ='unitname',related_name='dcline_warehouse_project_unit')
quantity=models.DecimalField(max_digits=12, decimal_places=4)
unit_rate=models.DecimalField(max_digits=12, decimal_places=2)
If I do either of the two (i.e. not both):
from projects.models import BOQItem, SalesInvoice, UnitItem, POItem
or
from warehouse.models import Warehouse
Its working great.
But if I import both if them (but hastag the codes which are actually using these imported models for foreignkey, so there's no probability of circular reference) then the error being shown is:
ImportError: cannot import name 'POItem'
Why is this happening and how can this be solved?
To explain the use case - Ive separate app for sales and warehouse department. Warehouse department creates warehuse object, which is required for creating Materail Request, Purchase Invoice, Indent, which would be created by the sales team.
Now, warehouse app has inventory model which should access the Bill of Quantity (orBoQ) (also called as Bill of Material or BoM) to be created by the sales team , Material Receipt Note model should access BoQ and Purchase Order and Delivery Challan (i.e. list of items to be delivered) should access the BoQ and sales invoice.
How can I solve this issue if Django doesn't allow:
from AppP.models import A,B,C inside AppQ and
from AppQ.models import X,Y,Z inside app AppP to be used simultaneously?
(I dont see any logic for this to not be allowed)
Thanks a lot for your effort and any solution would be appreciated.
I am a little saddened that I was given a down-vote because of poor indentation. Well,if u do downvote have the courtesy to comment and give reasons and provide an answer to the question (I strongly feel unless a question is off-topic/bad, there shan't be down-votes). This high handedness would never be taken care of by SO and its sad.
Nonetheless awaiting for any solution.Thanks in advance.
When you would like to use it as a ForeignKey in Django you could do this:
po_item= models.Foreignkey("project.POItem", related_name="foos")
You have to use the full name and put them in quotes.
This way you do not have to import the class at the top of the python file.

Categories

Resources