So I am trying to create an inline set similar to this image (http://oi48.tinypic.com/4gm5w2.jpg) so I can add multiple prices for different sizes for a product. I can't get it to even display the area in the django admin. On top of that by doing so I get the error:
<class 'apps.main.admin.PriceInline'>: (admin.E202) 'main.Apparel_Price' has no ForeignKey to 'main.Apparel_Price'.
models.py:
#python_2_unicode_compatible
class Apparel_Product(models.Model):
product_name = models.CharField(_("Name"), max_length=255)
default='media/None/no-img.jpg')
product_gender_type = models.CharField(max_length=256, choices=[('male', 'Male'), ('female', 'Female'), ('unisex', 'Unisex')])
product_brand = models.CharField(_("Brand"),max_length=25)
product_sizes = models.CharField(_("Sizes"),max_length=25)
product_colors = models.CharField(_("Colors"),max_length=25)
product_price = models.CharField(_("Price"),max_length=10)
product_description = models.CharField(_("Description"),max_length=500)
product_shipping_options = models.CharField(_("Shipping Options"),max_length=250)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = _("Apparel Product")
verbose_name_plural = _("Apparel Products")
def __str__(self):
return self.album_name
#python_2_unicode_compatible
class Apparel_Picture(models.Model):
master_apparel_product = models.ForeignKey(Apparel_Product, verbose_name=_("Apparel Product"), on_delete=models.CASCADE)
product_caption = models.CharField(_("Caption"), max_length=255)
product_photo = models.ImageField(_("Picture"), upload_to='media/')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = _("Picture")
verbose_name_plural = _("Pictures")
def __str__(self):
return self.photo_caption
#python_2_unicode_compatible
class Apparel_Price(models.Model):
# master_apparel_product = models.ForeignKey(Apparel_Product, verbose_name=_("Apparel Product"), on_delete=models.CASCADE)
master_apparel_product = models.OneToOneField(Apparel_Product, verbose_name=_("Apparel Product"), on_delete=models.CASCADE)
product_price = models.CharField(_("Price"), max_length=255)
product_size = models.ForeignKey(Apparel_Product, verbose_name=_("Apparel Product"), on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = _("Price")
verbose_name_plural = _("Prices")
def __str__(self):
return self.product_price
admin.py:
from django.contrib import admin
from .models import Apparel_Product, Apparel_Picture, Apparel_Price
# Register your models here.
def get_picture_preview(obj):
if obj.pk: # if object has already been saved and has a primary key, show picture preview
return """<img src="{src}" alt="{title}" style="max-width: 200px; max-height: 200px;" />""".format(
src=obj.photo.url,
title=obj.photo_caption,
)
return ("(choose a picture and save and continue editing to see the preview)")
get_picture_preview.allow_tags = True
get_picture_preview.short_description = ("Picture Preview")
class PictureInline(admin.StackedInline):
model = Apparel_Picture
extra = 0
fields = ["get_edit_link", "product_caption", "product_photo", get_picture_preview]
readonly_fields = ["get_edit_link", get_picture_preview]
def get_edit_link(self, obj=None):
if obj.pk: # if object has already been saved and has a primary key, show link to it
url = reverse('admin:%s_%s_change' % (obj._meta.app_label, obj._meta.model_name), args=[force_text(obj.pk)])
return """{text}""".format(
url=url,
text=_("Edit this %s separately") % obj._meta.verbose_name,
)
return ("(save and continue editing to create a link)")
get_edit_link.short_description = ("Edit link")
get_edit_link.allow_tags = True
class PriceInline(admin.TabularInline):
model = Apparel_Price
extra = 0
fields = ["price",]
#admin.register(Apparel_Product)
class Apparel_ProductAdmin(admin.ModelAdmin):
save_on_top = True
fields = ["product_name", "product_gender_type", "product_brand", "product_sizes", "product_colors", "product_price", "product_description", "product_shipping_options",]
inlines = [PictureInline]
#admin.register(Apparel_Picture)
class Apparel_PictureAdmin(admin.ModelAdmin):
save_on_top = True
fields = ["master_apparel_product", "product_caption", "product_photo", get_picture_preview]
readonly_fields = [get_picture_preview]
#admin.register(Apparel_Price)
class Apparel_PriceAdmin(admin.ModelAdmin):
save_on_top = True
fields = ["master_apparel_product", "product_price",]
inlines = [PriceInline,]
So I am really confused how main.Apparel_Price would need a foreign key to itself. The one for the picture works but the one for the prices do not and I tried copying them and it didn't work. Help would greatly be appreciated.
PriceInline has model Apparel_Price same as Apparel_PriceAdmin. Just use PriceInline as inline in Apparel_ProductAdmin.
Related
here is my model:
class Product(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
name = models.CharField(max_length=200)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
objects = models.Manager()
available = ProductStockManager()
and I have a form like this:
class ProductForm(ModelForm):
name = forms.CharField(max_length=200)
price = forms.DecimalField(decimal_places=2)
description = forms.Textarea()
class Meta:
model = Product
fields = ['category', 'name', 'description', 'price', 'stock']
def clean_description(self):
pass
def clean_price(self):
pass
def clean_name(self):
pass
in my form when I use clean_field() for each field it makes is_valid() False except clean_description() what is this for ?
why when I use clean_price(), clean_name() my is_valid() returns False?
and why it doesn't when I use clean_description() ?
I have 2 tables in my models.py. I'm trying to auto fill the user filed in the second table whatever user I select in my first table I tried to override the save_model in admins.py but it didn't work. Here is my models.py file:
class Company(models.Model):
company_name = models.CharField(max_length = 50)
slug = models.SlugField(unique = True)
user = models.ManyToManyField(User, related_name='company_user')
objects = models.Manager()
published = PublishedManager()
def __str__(self):
return self.company_name
class Group(models.Model):
company_name = models.ForeignKey(Company, related_name = 'co_name',
on_delete=models.CASCADE)
count = models.CharField(max_length = 50)
real_count = models.CharField(max_length = 50)
entry_date = models.DateTimeField()
exit_date = models.DateTimeField()
code = models.CharField(max_length = 10)
code_date = models.DateTimeField()
manifest = models.ImageField(upload_to='manifest/%m/%y', blank=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
user = models.ManyToManyField(User, related_name='group_user', blank=True)
objects = models.Manager()
published = PublishedManager()
class Meta:
ordering = ('-code_date',)
def __str__(self):
return str(self.id)
my admins.py file
#admin.register(Group)
class GroupAdmin(admin.ModelAdmin):
list_display = ['id', 'company_name', 'code', 'code_date', 'count',
'real_count', 'entry_date', 'exit_date',
'manifest', 'created'
]
autocomplete_fields = ('user',)
#admin.register(Company)
class CompanyAdmin(admin.ModelAdmin):
list_display = ['company_name']
autocomplete_fields = ('user',)
prepopulated_fields = {'slug': ('company_name',)}
views.py
#login_required
def main_approval(request):
groups = Group.objects.filter(user=request.user)
context = {'groups': groups}
return render(request, 'approval/main_list.html', context)
I'm trying to get the user in the Company class to be auto inserted in my Group class
Any advice?
Try to do this in views.py
user = self.company_name.user.all()
I have 4 related models and I need to implement the functionality to consistently create instances of these models in a database in one post query. For this I use override of the APIView class post method.
models
class VendorContacts(models.Model):
contact_id = models.AutoField(primary_key=True)
vendor = models.OneToOneField('Vendors', on_delete=models.CASCADE)
contact_name = models.CharField(max_length=45, blank=True)
phone = models.CharField(max_length=45, blank=True)
email = models.CharField(max_length=80, blank=True, unique=True)
class Meta:
db_table = 'vendor_contacts'
class VendorModuleNames(models.Model):
vendor = models.OneToOneField('Vendors', on_delete=models.CASCADE, primary_key=True)
module = models.ForeignKey(Modules, models.DO_NOTHING)
timestamp = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'vendor_module_names'
unique_together = (('vendor', 'module'),)
class Vendors(models.Model):
COUNTRY_CHOICES = tuple(COUNTRIES)
vendorid = models.AutoField(primary_key=True)
vendor_name = models.CharField(max_length=45, unique=True)
country = models.CharField(max_length=45, choices=COUNTRY_CHOICES)
nda = models.DateField(blank=True, null=True)
user_id = models.ForeignKey('c_users.CustomUser', on_delete=models.PROTECT)
timestamp = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'vendors'
unique_together = (('vendorid', 'timestamp'),)
class Modules(models.Model):
MODULES_NAME =tuple(MODULES)
mid = models.AutoField(primary_key=True)
module_name = models.CharField(max_length=50, choices=MODULES_NAME)
active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'modules'
unique_together = (('mid', 'timestamp'),)
serializer.py
class VendorsSerializer(serializers.ModelSerializer):
class Meta:
model = Vendors
fields = ('vendor_name',
'country',
'nda',)
class VendorContactSerializer(serializers.ModelSerializer):
class Meta:
model = VendorContacts
fields = (
'contact_name',
'phone',
'email',)
class VendorModulSerializer(serializers.ModelSerializer):
class Meta:
model = VendorModuleNames
fields = ('module',)
class ModulesSerializer(serializers.ModelSerializer):
class Meta:
model = Modules
fields = ('module_name', )
views.py
class VendorsCreateView(APIView):
"""Create new vendor instances from form"""
def post(self, request, *args, **kwargs):
vendor_serializer = VendorsSerializer(data=request.data)
vendor_contact_serializer = VendorContactSerializer(data=request.data)
vendor_modules_serializer = VendorModulSerializer(data=request.data)
module_serializer = ModulesSerializer(data=request.data)
try:
vendor_serializer.is_valid(raise_exception=True) \
and vendor_contact_serializer.is_valid(raise_exception=True) \
and vendor_modules_serializer.is_valid(raise_exception=True) \
and module_serializer.is_valid(raise_exception=True)
vendor_serializer.save(user_id=request.user)
# ....
# Some new logic here ????
# ...
except ValidationError:
return Response({"errors": (vendor_serializer.errors,
vendor_contact_serializer.errors,
vendor_modules_serializer.errors
)},
status=status.HTTP_400_BAD_REQUEST)
else:
return Response(request.data, status=status.HTTP_200_OK)
There is no problem saving one Vendor model, but I can't imagine how to save cascading all related models in a single request.
save returns the newly saved object, which you can then pass into the subsequent save() methods:
vendor = vendor_serializer.save(user_id=request.user)
module = module_serializer.save()
vendor_module = vendor_modules_serializer.save(module=module, vendor=vendor)
vendor_contact = vendor_contact_serializer.save(vendor=vendor)
I'm facing below issue in ModelSerializer file upload.
Issue 1) I'm trying to upload files using ModelSerializer. I have two models BlogFilesSerializer and BlogSerializer. when trying to upload a file it shows too many values to unpack error and I know its meaning why is this occurring but don't know how to handle these exceptions.
serializers.py
class BlogFilesSerializer(ModelSerializer):
created_at = serializers.SerializerMethodField()
updated_at = serializers.SerializerMethodField()
class Meta:
model = BlogFilesModel
fields = ('blog_files_id', 'blog', 'path',
'created_at', 'updated_at')
class BlogSerializer(ModelSerializer):
blog_files = serializers.SerializerMethodField()
uploaded_files = serializers.FileField(required=True, source='*')
blog_created_at = serializers.SerializerMethodField()
def get_blog_files(self, obj):
info = BlogFilesSerializer(BlogFilesModel.objects.filter(
blog=obj).order_by('-pk'), many=True)
if info.data:
for i in info.data:
user_detail = User.objects.get(pk=obj.user.id)
i.__setitem__('user_detail', UserSerializer(user_detail).data)
if i.get('user_detail'):
try:
del i['user_detail']['password']
except expression as identifier:
pass
return info.data
def get_blog_created_at(self, obj):
formatted_date = obj.created_at.strftime("%d-%m-%Y")
return formatted_date
class Meta:
model = BlogModel
fields = ('blog_id', 'user', 'title', 'content',
'status',
'blog_files', 'blog_created_at',
'uploaded_files'
)
def create(self, validated_data):
instance = BlogModel.objects.create(**validated_data)
return instance
views.py
class BlogViewSet(viewsets.ModelViewSet):
queryset = BlogModel.objects.all()
lookup_field = 'blog_id'
serializer_class = BlogSerializer
parser_classes = (MultiPartParser, FormParser,FileUploadParser)
models.py
class BlogModel(models.Model):
BLOG_STATUS = (
('PUBLISH', 'Publish'),
('DRAFT', 'Draft'),
)
blog_id = models.AutoField(primary_key=True)
user = models.ForeignKey(
User, on_delete=models.CASCADE, related_name='blogs')
title = models.CharField(max_length=255)
content = models.TextField(blank=True, null=True)
status = models.CharField(max_length=7, choices=BLOG_STATUS)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta():
db_table = 'blogs'
verbose_name = 'Blog'
verbose_name_plural = 'Blogs'
def __str__(self):
return self.title
#property
def files(self):
return 'something'
def blog_directory_path(instance, filename):
return 'uploads/blogs/{}'.format(filename+str(datetime.now()))
class BlogFilesModel(models.Model):
blog_files_id = models.AutoField(primary_key=True)
blog = models.ForeignKey(
BlogModel, on_delete=models.CASCADE, related_name='blogs',blank=True)
path = models.FileField(blank=False, null=False,upload_to=blog_directory_path)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta():
db_table = 'blog_files'
verbose_name = 'Blog'
verbose_name_plural = 'Blogs'
def __str__(self):
return str(self.path)
Issue 2) i'm also unable to select multiple files for upload in BlogSerializer and in field uploaded_files = serializers.FileField(required=True, source='*') and their is no detailed explanation is DRF documentation. How can i add multple attribute to file field.
EDIT 1: I tried and got till here in def to_internal_value(self, data): the field.source_attrs = [] their is no key so i'm getting this error.
in my ModelSerializer i tried this uploaded_files = serializers.FileField(required=True, source='files') added files as property to BlogModel now i'm getting 'Error = files' is an invalid keyword argument for this function can someone guide me here.
Hope is have explained my problem well.
Thank you.
I am trying to give posts category choices , everything works fine but if I add posts from admin panel I get error something like this
Select a valid choice. SSC is not one of the available choices.
this is my Posts/models.py
from django.db import models
from django.core.validators import FileExtensionValidator
# Create your models here.
CATEGORIES = (
('SSC', 'SSCQUESTION'),
('CAT', 'CATQUESTION'),
)
class Category(models.Model):
title = models.CharField(max_length = 120, verbose_name="Title" )
updated_at = models.DateTimeField(auto_now_add=True, verbose_name="Updated at")
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at")
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
ordering = ['title']
def __str__(self):
return self.title
class Posts(models.Model):
title = models.CharField(max_length=60)
file_upload = models.FileField(null= True, blank=True, validators=[FileExtensionValidator(['pdf'])])
content = models.TextField()
category = models.ForeignKey(Category, null= True,verbose_name="Category", on_delete=models.CASCADE,choices = CATEGORIES)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
# class Meta:
# verbose_name = "Post"
# verbose_name_plural = "Posts"
# ordering = ['-created_at']
def __unicode__(self):
return self.title
def __str__(self):
return self.title
In admin panel this gives error like this
remove choices
category = models.ForeignKey(Category, null= True,verbose_name="Category", on_delete=models.CASCADE)
Go to the Category table in the admin panel and create some categories there.. Those categories will now be populated in the dropdown in the Post creation page