I was looking on customizing admin where i found tabularinline model which allow us to edit on the same page. But i got confused as my tables are reference in multiple places. I could not understand which model should i make tabular inline.
for example here is my model
class ProductType(ModelWithMetadata):
name = models.CharField(max_length=150, help_text="type of product. ex - accessories, apparel")
slug = models.SlugField(max_length=150, unique=True)
is_shipping_required = models.BooleanField(default=True)
class Meta:
ordering = ("slug",)
app_label="products"
class Category(MPTTModel, ModelWithMetadata):
name = models.CharField(max_length=128)
slug = models.SlugField(max_length=128)
description = models.TextField(blank=True)
parent = models.ForeignKey(
"self", null=True, blank=True, related_name="children", on_delete=models.CASCADE
)
objects = models.Manager()
tree = TreeManager()
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
def __str__(self):
return self.name
class Product(ModelWithMetadata, PublishableModel):
product_type = models.ForeignKey(
ProductType, related_name="products", on_delete=models.CASCADE
)
name = models.CharField(max_length=128)
slug = models.SlugField()
category = models.ForeignKey(
Category,
related_name="products",
on_delete=models.SET_NULL,
null=True,
blank=True,
)
isAvailable = models.BooleanField(default=True)
isDiscount = models.BooleanField(default=False)
charge_taxes = models.BooleanField(default=False)
updated_at = models.DateTimeField(auto_now=True, null=True)
class Meta:
verbose_name = "product"
verbose_name_plural = "products"
ordering = ("name",)
constraints = [
models.UniqueConstraint(
fields=["article_number", "slug"], name="unique article number and slug")
]
class ProductVariant(ModelWithMetadata):
sku = models.CharField(max_length=255, unique=True)
name = models.CharField(max_length=255, blank=True)
currency = models.CharField(
max_length=settings.DEFAULT_CURRENCY_CODE_LENGTH,
default=settings.DEFAULT_CURRENCY,
blank=True,
null=True,
)
price_override_amount = models.DecimalField(
max_digits=settings.DEFAULT_MAX_DIGITS,
decimal_places=settings.DEFAULT_DECIMAL_PLACES,
blank=True,
null=True,
)
product = models.ForeignKey(
Product, related_name="variants", on_delete=models.CASCADE
)
images = models.ManyToManyField("ProductImage", through="VariantImage")
track_inventory = models.BooleanField(default=True)
class BaseAssignedAttribute(models.Model):
assignment = None
values = models.ManyToManyField("AttributeValue")
class AttributeValue(models.Model):
name = models.CharField(max_length=250)
value = models.CharField(max_length=100, blank=True, default="")
slug = models.SlugField(max_length=255)
attribute = models.ForeignKey(
"Attribute", related_name="values", on_delete=models.CASCADE
)
class AssignedProductAttribute(BaseAssignedAttribute):
"""Associate a product type attribute and selected values to a given product."""
product = models.ForeignKey(
Product, related_name="attributes", on_delete=models.CASCADE
)
assignment = models.ForeignKey(
"ProductAttribute", on_delete=models.CASCADE, related_name="productassignments"
)
class Meta:
unique_together = (("product", "assignment"),)
class AssignedVariantAttribute(BaseAssignedAttribute):
"""Associate a product type attribute and selected values to a given variant."""
variant = models.ForeignKey(
ProductVariant, related_name="attributes", on_delete=models.CASCADE
)
assignment = models.ForeignKey(
"AttributeVariant", on_delete=models.CASCADE, related_name="variantassignments"
)
class Meta:
unique_together = (("variant", "assignment"),)
class AttributeVariant(models.Model):
attribute = models.ForeignKey(
"Attribute", related_name="attributevariant", on_delete=models.CASCADE
)
product_type = models.ForeignKey(
ProductType, related_name="attributevariant", on_delete=models.CASCADE
)
assigned_variants = models.ManyToManyField(
ProductVariant,
blank=True,
through=AssignedVariantAttribute,
through_fields=("assignment", "variant"),
related_name="attributesrelated",
)
class Attribute(models.Model):
name = models.CharField(max_length=30, unique=True)
slug = models.SlugField(max_length=250, unique=True)
product_types = models.ManyToManyField(
ProductType,
blank=True,
related_name="product_attributes",
through="ProductAttribute",
through_fields=("attribute", "product_type"),
)
product_variant_types = models.ManyToManyField(
ProductType,
blank=True,
related_name="variant_attributes",
through=AttributeVariant,
through_fields=("attribute", "product_type"),
)
class ProductAttribute(models.Model):
attribute = models.ForeignKey(
"Attribute", related_name="attributeproduct", on_delete=models.CASCADE
)
product_type = models.ForeignKey(
ProductType, related_name="attributeproduct", on_delete=models.CASCADE
)
assigned_products = models.ManyToManyField(
Product,
blank=True,
through=AssignedProductAttribute,
through_fields=("assignment", "product"),
related_name="attributesrelated",
)
I am confused on the tables AttributeValue, AssignedProductAttribute, AssignedVariantAttribute, AttributeVariant, Attribute and ProductAttribute. Attribute is related to ProductAttribute and is also related to AttributeVariant and AttributeValue. Similarly, in the case of variant.
I could not figure out which table should be inline and where should i reference that inlined table. Because of various relationship, i am not sure of those things.
Related
I am trying to display a product list page with products attributes along with category which is a MPTT field. I want to display the category assigned to that particular product in the product list page. How can i achieve this?
Models
class Category(MPTTModel):
"""
Inventory Category table implimented with MPTT
"""
name = models.CharField(
max_length=100,
null=False,
unique=False,
blank=False,
verbose_name=_("category name"),
help_text=_("format: required, max-100"),
)
slug = AutoSlugField(populate_from='name')
cat_img = models.ImageField(upload_to='images/categories/')
parent = TreeForeignKey(
"self",
on_delete=models.PROTECT,
related_name="children",
null=True,
blank=True,
unique=False,
verbose_name=_("parent of category"),
help_text=_("format: not required"),
)
class MPTTMeta:
order_insertion_by = ["name"]
class Meta:
verbose_name = _("product category")
verbose_name_plural = _("product categories")
def __str__(self):
return self.name
class Product(models.Model):
"""
Product details table
"""
product_id = models.UUIDField(default=uuid.uuid4, editable=False)
sku = models.CharField(max_length=255, blank=True, null=True)
name = models.CharField(
max_length=255,
unique=False,
null=False,
blank=False,
verbose_name=_("product name"),
help_text=_("format: required, max-255"),
)
slug = AutoSlugField(populate_from='name')
price = models.DecimalField(max_digits=6, decimal_places=2, null=True, blank=True)
description = models.TextField(
unique=False,
null=True,
blank=True,
verbose_name=_("product description"),
help_text=_("format: required"),
)
prd_img = models.ImageField(upload_to='images/products/', null=True, blank=True)
category = TreeManyToManyField(Category, null=True, blank=True)
modifier_group = models.ManyToManyField(ModifierGroup, null=True, blank=True)
def __str__(self):
return self.name
Views
#login_required(login_url='/login/')
def productList(request):
products = Product.objects.all()
context = {'products':products}
template = 'product/product/products.html'
return render(request,template,context)
Template
<td class="text-end pe-0" data-order="37">
<span class="fw-bold ms-3">{{product.category.name}}</span>
</td>
Template Result
How can i query and display the category for that particular product in the product list page?
I have created a Django filter set to filter data, some fields are filtered with relationships.
When I never filter with the endpoint, it just returns all data instead of filtered data, what could be wrong here?
This is my endpoint filterer :
http://127.0.0.1:5000/api/v1/qb/questions/?paper=26149c3b-c3e3-416e-94c4-b7609b94182d§ion=59bdfd06-02d4-4541-9478-bf495dafbee1&topic=df8c2152-389a-442f-a1ce-b56d04d39aa1&country=KE
Below is my sample :
from django_filters import rest_framework as filters
class QuestionFilter(filters.FilterSet):
topic = django_filters.UUIDFilter(label='topic',
field_name='topic__uuid',
lookup_expr='icontains')
sub_topic = django_filters.UUIDFilter(label='sub_topic',
field_name='topic__sub_topic__uuid',
lookup_expr='icontains')
paper = django_filters.UUIDFilter(label='paper',
field_name='paper__uuid',
lookup_expr='icontains')
section = django_filters.UUIDFilter(label='section',
field_name='section__uuid',
lookup_expr='icontains')
subject = django_filters.UUIDFilter(label='subject',
field_name="paper__subject__id",
lookup_expr='icontains'
)
year = django_filters.UUIDFilter(label='year',
field_name='paper__year__year',
lookup_expr="icontains")
country = django_filters.CharFilter(label='country',
field_name="paper__exam_body__country",
lookup_expr='icontains')
class Meta:
model = Question
fields = ['topic', 'section', 'paper', 'sub_topic', 'subject', 'year',
'country']
Then my view is like this :
class QuestionView(generics.ListCreateAPIView):
"""Question view."""
queryset = Question.objects.all()
serializer_class = serializers.QuestionSerializer
authentication_classes = (JWTAuthentication,)
filter_backends = (filters.DjangoFilterBackend,)
filterset_class = QuestionFilter
Then the models attached to the filter are as below :
class Question(SoftDeletionModel, TimeStampedModel, models.Model):
"""Questions for a particular paper model."""
uuid = models.UUIDField(unique=True, max_length=500,
default=uuid.uuid4,
editable=False,
db_index=True, blank=False, null=False)
mentor = models.ForeignKey(User, related_name='question_mentor', null=True,
on_delete=models.SET_NULL)
paper = models.ForeignKey(Paper, max_length=25, null=True,
blank=True, on_delete=models.CASCADE)
question = models.TextField(
_('Question'), null=False, blank=False)
section = models.ForeignKey(QuestionSection,
related_name='section_question',
null=True, on_delete=models.SET_NULL)
topic = models.ForeignKey(Course, related_name='topic_question',
null=True, on_delete=models.SET_NULL)
question_number = models.IntegerField(_('Question Number'), default=0,
blank=False, null=False)
image_question = models.ImageField(_('Image question'),
upload_to='image_question',
null=True, max_length=900)
answer_locked = models.BooleanField(_('Is Answer locked'), default=True)
status = models.CharField(max_length=50, choices=QUESTION_STATUSES,
default=ESSAY)
address_views = models.ManyToManyField(CustomIPAddress,
related_name='question_views',
default=None, blank=True)
bookmarks = models.ManyToManyField(User, related_name='qb_bookmarks',
default=None, blank=True)
def __str__(self):
return f'{self.question}'
Paper Model
class Paper(SoftDeletionModel, TimeStampedModel, models.Model):
"""Paper model."""
uuid = models.UUIDField(unique=True, max_length=500,
default=uuid.uuid4,
editable=False,
db_index=True, blank=False, null=False)
subject = models.ForeignKey(Subject, related_name='subject',
null=True, on_delete=models.SET_NULL)
mentor = models.ForeignKey(User, related_name='paper_mentor', null=True,
on_delete=models.SET_NULL)
year = models.DateField(_('Year'), blank=False, null=False)
grade_level = models.ForeignKey(ClassGrade, related_name='grade_paper',
null=True, on_delete=models.SET_NULL)
exam_body = models.ForeignKey(ExamBody, related_name='exam_body_paper',
null=True, on_delete=models.SET_NULL)
number_of_questions = models.IntegerField(_('No of questions'),
blank=False, null=False)
number_of_sections = models.IntegerField(_('No of sections'),
blank=False, null=False)
color_code = ColorField(format='hexa', default='#33AFFF', null=True)
class Meta:
ordering = ['created']
def __str__(self):
return f'{self.subject.name} ({self.year})'
QuestionSection Model :
class QuestionSection(SoftDeletionModel, TimeStampedModel, models.Model):
"""Question paper sections e.g Section A, B, C etc."""
uuid = models.UUIDField(unique=True, max_length=500,
default=uuid.uuid4,
editable=False,
db_index=True, blank=False, null=False)
section = models.CharField(
_('Question Section'), max_length=100, null=False, blank=False)
def __str__(self):
return f'{self.section}'
class Course(SoftDeletionModel, TimeStampedModel, models.Model):
"""
Topic model responsible for all topics.
"""
uuid = models.UUIDField(unique=True, max_length=500,
default=uuid.uuid4,
editable=False,
db_index=True, blank=False, null=False)
title = models.CharField(
_('Title'), max_length=100, null=False, blank=False)
overview = models.CharField(
_('Overview'), max_length=100, null=True, blank=True)
description = models.CharField(
_('Description'), max_length=200, null=False, blank=False
)
country = CountryField()
subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
topic_cover = models.ImageField(
_('Topic Cover'), upload_to='courses_images',
null=True, blank=True, max_length=900)
grade_level = models.ForeignKey(
ClassGrade, max_length=25, null=True,
blank=True, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
ranking = models.IntegerField(
_('Ranking of a Topic'), default=0, help_text=_('Ranking of a Topic')
)
def __str__(self):
return self.title
class Meta:
verbose_name_plural = "Topics"
ordering = ['ranking']
I want to query from OrderItem Model like
total_orders = OrderItem.objects.filter(product.user == request.user.id).count()
but i am getting error
**
NameError at /home
name 'product' is not defined
**
MY MODELS:
Product Model:
class Product(models.Model):
title = models.CharField(max_length=150)
user = models.ForeignKey(
User, blank=True, null=True, on_delete=models.SET_DEFAULT, default=None)
description = models.TextField()
price = models.FloatField()
quantity = models.IntegerField(default=False, null=True, blank=False)
minorder = models.CharField(
max_length=150, help_text='Minum Products that want to sell on per order', null=True, default=None, blank=True)
image = models.ImageField()
category = models.ForeignKey(
Categories, default=1, on_delete=models.CASCADE)
slug = models.SlugField(blank=True, unique=True)
def __str__(self):
return self.title
Order Item Model
class OrderItem(models.Model):
product = models.ForeignKey(
Product, on_delete=models.SET_NULL, blank=True, null=True)
order = models.ForeignKey(
Order, on_delete=models.SET_NULL, blank=True, null=True)
quantity = models.FloatField(default=0, null=True, blank=True)
date_orderd = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(
User, on_delete=models.SET_NULL, blank=True, null=True)
price = models.FloatField(blank=True, null=True)
def __str__(self):
return str(self.product)
My View:
def home(request):
total_orders = OrderItem.objects.filter(
product.user == request.user.id).count()
return render(request, "sellerprofile/home.html", {'total_orders': total_orders})
Do:
total_orders = OrderItem.objects.filter(product__user=request.user).count()
You can look at the documentation here about field lookups on more detail.
I have three models, BoletoConfig(BilletConfig),Tickets and CategoryTicket, one ticket has a CategoryTicket and CategoryTicket has a BilletConfig, BilletConfig has an attribute with the days for the billet due, I want to create a method in the tickets class to calculate the due date.
I have doubts if I use the decorator #property or #classmethod, which would be the best choice and why? and how would i get the value of days_to_become_due from my BoletoConfig class in tickets?
This my /billets/models.BoletoConfig
class BoletoConfig(models.Model):
base_amount = models.DecimalField(
db_column='valor_base',
max_digits=10,
decimal_places=2,
verbose_name='valor base do boleto',
)
check_specialization_for_amount = models.BooleanField(
default=False,
db_column='especializacao_protocolo',
verbose_name='especialização do protocolo',
)
days_to_become_due = models.IntegerField(
db_column='dias_vencimento',
verbose_name='dias até vencimento',
)
class Meta:
db_table = 'boletos_boleto_configuracao'
verbose_name = 'boletos_configuração'
def __str__(self):
return self.base_amount
This my /tickets/models.tickets
class Ticket(TimestampedModel, permissions.TicketPermission):
"""A ticket requested by someone to address a situation"""
requested_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
models.PROTECT,
db_column='requerido_por',
related_name='+',
)
show_ticket_for_request_user = models.BooleanField(
default=True,
db_column='mostrar_ticket_para_requerente',
)
message = models.CharField(
max_length=4000,
blank=True,
null=True,
db_column='mensagem',
)
status = models.ForeignKey(
Status,
models.PROTECT,
)
category = models.ForeignKey(
Category,
models.PROTECT,
)
files = models.CharField(max_length=4000, blank=True, null=True)
boleto_id = models.UUIDField(
db_column='boleto_id',
verbose_name='Uuid Boleto',
null=True,
blank=True,
)
#classmethod
def get_boleto_duo_date(self, category):
days_to_due = 'category__boleto_config__days_to_become_due'
return self.ticket.created_at + timedelta(days=days_to_due)
This my /tickets/models.CategoryTicket
class Category(TimestampedModel):
"""
Represents what the ticket is about.
EX: Change lesson attendance, change activity grade.
"""
.
.
.
.
boleto_config = models.ForeignKey(
BoletoConfig,
models.PROTECT,
db_column='boleto_config_id',
verbose_name='configuração de boleto',
null=True,
blank=True,
)
I have two models ProductTypeModel and ProductModel, product_type is the foreign key in the product. Then I wrote a ModelSerializer for a product to get all the entries of ProductModel and along with some additional info.
Now I'm unable to get product_sub_type from the ProductTypeModel in ProductSerializer
I have tried SlugRelatedField in serializers, tried to set slug_field=product_sub_type and slug_field=product_type__product_sub_type and slug_field=product_type.product_sub_type
models.py
class ProductType(models.Model):
"""Product type model."""
id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False
)
hsn = models.ForeignKey(
HSN,
related_name='product_types',
on_delete=models.SET_NULL,
null=True, blank=True
)
product_type = models.CharField(max_length=255, null=True, blank=True)
product_sub_type = models.CharField(max_length=255, db_index=True)
description = models.CharField(max_length=255, null=True, blank=True)
def __str__(self):
return str(self.product_type)
def get_sub_type(self):
return str(self.product_sub_type)
class Meta:
db_table = 'ProductTypes'
unique_together = ('product_type', 'product_sub_type')
class Product(models.Model):
"""Products model."""
product_id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False
)
product_type = models.ForeignKey(
ProductType,
related_name='related_products',
on_delete=models.SET_NULL,
blank=True, null=True
)
name = models.CharField(max_length=255, db_index=True)
code_name = models.CharField(max_length=255, null=True, blank=True)
href = models.CharField(max_length=500, blank=True, null=True)
full_name = models.CharField(max_length=255, null=True, blank=True, db_index=True)
manufacturer = models.ForeignKey(
Manufacturer,
related_name='manufactured_products',
on_delete=models.SET_NULL,
null=True, blank=True
)
packing = models.CharField(max_length=255, null=True, blank=True)
packing_detail = models.CharField(max_length=255, null=True, blank=True)
mrp = models.DecimalField(
max_digits=8,
decimal_places=2,
null=True, blank=True
)
created_at = models.DateTimeField(
'created at',
db_index=True,
default=timezone.now
)
def __str__(self):
return str(self.full_name)
class Meta:
db_table = 'Products'
unique_together = ('code_name', 'product_type')
serializers.py
class ProductTypeSerializer(serializers.ModelSerializer):
# Serialize/Deserialize ProductType instance.
class Meta:
model = ProductType
fields = (
'id', 'hsn',
'product_type', 'product_sub_type',
'description'
)
read_only_fields = ('id', )
class ProductSerializer(serializers.ModelSerializer):
# Serialize/Deserialize Product instance.
manufacturer = serializers.StringRelatedField()
manufacturer_id = serializers.PrimaryKeyRelatedField(read_only=True)
product_sub_type = serializers.SlugRelatedField(slug_field=????)
class Meta:
model = Product
fields = (
'product_id',
'product_type', 'product_sub_type',
'name', 'code_name',
'manufacturer', 'manufacturer_id',
'full_name',
'packing', 'packing_detail',
'mrp'
)
read_only_fields = (
'product_id', 'created_at',
'product_type', 'manufacturer_id'
)
with slug_field=product_sub_type it returns
ImproperlyConfigured at /products/
Field name product_sub_type is not valid for model Product.
with slug_field=product_type.product_sub_type it returns
AttributeError at /products/
Got AttributeError when attempting to get a value for field product_sub_type on serializer ProductSerializer.The serializer field might be named incorrectly and not match any attribute or key on the Product instance.
I want the serializer to return something like this:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"product_id": "fffcf7ba-5c6d-4190-96d2-cc9125e18e71",
"product_type": "1b3dd955-b67e-4ca3-9561-6d1704ff7c91",
"product_sub_type": "Capsules",
"name": "Enshine Toothpaste",
"code_name": null,
"manufacturer": "Leeford Healthcare Ltd",
"manufacturer_id": 2524,
"full_name": "Enshine Toothpaste",
"packing": null,
"packing_detail": null,
"mrp": null
}
]
}
Providing the attributes slug_field and source works for a read-only SlugRelatedField. To allow writing in this field the queryset attribute must also be provided
class ProductSerializer(serializers.ModelSerializer):
...
product_sub_type = serializers.SlugRelatedField(
slug_field='product_sub_type',
source='product_type',
queryset=ProductType.objects.all()
)
According to documentation slug_field should be a field that uniquely identifies any given instance