Unable to Understand the below statements of models in Django - django

I am naive in Django, I have done a sample E-commerce application that is present online. I am unable to understand the highlighted statements, I searched online but unable to understand the statements.
Can someone please explain me like below
productitems = self.name_set.all()
From where this name_set.all() came ?????????
orderItems = self.orderitem_set.all()
likewise from where orderitem_set.all() ?????????
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Customer(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE, null=True,blank=True)
name = models.CharField(max_length=200,null=True)
email = models.CharField(max_length=200,null=True)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=200, null=True)
price = models.DecimalField(max_digits=7,decimal_places=2)
digital = models.BooleanField(default=False,null=True,blank=False)
image = models.ImageField(null=True,blank=True)
#image
def __str__(self):
return self.name
#property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
#property
def get_product_total(self):
**productitems = **self.name_set.all()****
total = sum([item.get_total for item in productitems])
return total
print('total:',total)
class Order(models.Model):
customer = models.ForeignKey(Customer,on_delete=models.SET_NULL,blank=True,null=True)
date_ordered=models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False,null=True,blank=False)
transaction_id = models.CharField(max_length=200, null=True)
def __str__(self):
return str(self.id)
#property
def shipping(self):
shipping = False
orderItems = **self.orderitem_set.all()**
for i in orderItems:
if i.product.digital == False:
shipping = True
return shipping
#property
def get_cart_total(self):
orderitems = self.orderitem_set.all()
total = sum([item.get_total for item in orderitems])
return total
#property
def get_cart_items(self):
orderitems = self.orderitem_set.all()
total = sum([item.quantity for item in orderitems])
return total
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.IntegerField(default=0,blank=True,null=True)
date_added=models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.product)
#property
def get_total(self):
print(self.product.price)
# print("self.product.price:",self.product.price)
# print("self.quantity:", self.quantity)
total = self.product.price * self.quantity
return total
class ShippingAddress(models.Model):
customer = models.ForeignKey(Customer,on_delete=models.SET_NULL,blank=True,null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, blank=True, null=True)
address = models.CharField(max_length=200,null=True)
city = models.CharField(max_length=200, null=True)
state = models.CharField(max_length=200, null=True)
zipcode = models.CharField(max_length=200, null=True)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.address)

Those are reverse foreign key lookups. The {field_name}_set pattern is what Django uses by default if you don't define a different term yourself.
The Django documentation explains it more here https://docs.djangoproject.com/en/3.1/ref/models/fields/#django.db.models.ForeignKey.related_name
and here https://docs.djangoproject.com/en/3.1/topics/db/queries/#following-relationships-backward
An example from the docs is:
>>> b = Blog.objects.get(id=1)
>>> b.entry_set.all() # Returns all Entry objects related to Blog.
Instead of using the default you can set the related lookup to a custom value when defining the ForeignKey field on the model, using the related_name argument. I do this often myself, there are usually more fitting terms for the project than the default.

Related

Query with multiple foreign keys (django)

I'm making a searchbar for a site I'm working on and I'm having trouble when I want to filter different fields from different models (related between them) Here are my models:
class Project(models.Model):
name = models.CharField(max_length=250)
objective = models.CharField(max_length=250)
description = models.TextField()
launching = models.CharField(max_length=100, null=True, blank=True)
image = models.ImageField(
upload_to='imgs/', null=True, blank=True)
image_thumbnail = models.ImageField(
upload_to='thumbnails/', null=True, blank=True)
slug = models.CharField(max_length=250)
class Meta:
db_table = 'project'
def __str__(self):
return self.name
class Institution(models.Model):
name = models.CharField(max_length=250)
project = models.ManyToManyField(Proyecto)
class Meta:
db_table = 'institution'
def __str__(self):
return self.name
And I want to be able to search by the name of the project or the institution, but my code only takes the institution's name.
def searchbar(request):
if request.method == 'GET':
search = request.GET.get('search')
post = Project.objects.all().filter(name__icontains=search, institution__name__icontains=search)
return render(request, 'searchbar.html', {'post': post, 'search': search})
How can I search for all the projects that match by its name OR the institution's name?
BTW, I'm using SQL, not sure if it's relevant, but I thought I should add that info.
You can .filter(…) [Django-doc] with Q objects [Django-doc]:
from django.db.models import Q
Project.objects.filter(Q(name__icontains=search) | Q(institution__name__icontains=search))
or you can work with the _connector parameter:
from django.db.models import Q
Project.objects.filter(
name__icontains=search,
institution__name__icontains=search,
_connector=Q.OR
)

Foreign key with multiple models?

I am creating ecommerce website. There are multiple categories. For example, phones, computers and others. I created a model for each of them. In OrderItems I want to foreign key each of them. So, I want to use multiple models in ForeignKey.
models.py
class Telefon(models.Model):
name = models.CharField(max_length=200)
category = models.CharField(max_length=300, choices=TELEFON, default="xiaomi")
price = models.FloatField()
image = models.ImageField(null=True, blank=True)
def __str__(self):
return self.name
#property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
class TV(models.Model):
name = models.CharField(max_length=200)
category = models.CharField(max_length=300, choices=TELEFON, default="xiaomi")
price = models.FloatField()
image = models.ImageField(null=True, blank=True)
def __str__(self):
return self.name
#property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
Product={'Telefon', 'TV'}
class OrderItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
#property
def get_total(self):
total = self.product.price * self.quantity
return total
So, how can I use multiple models in Foreign Key field in my OrderItems model.

I'm optimizing my django project backend, but I got many problems on "list_display" that contains ForeignKey

django masters all around the world
I'm Korean developer and started django 3 months ago.
Now I'm just a slave of my company.
Anyway, I have problem on optimizing django admin project, but no one has experienced the same problem.
This is my models "Project", "Answer", "Request".
# ------------------------------------------------------------------
# Model : Project
# Description : project model
# ------------------------------------------------------------------
class Project(models.Model):
class Meta:
verbose_name = ' project'
verbose_name_plural = ' project'
def __str__(self):
return str(self.id)
# ------------------------------------------------------------------
# Model : Request
# Description : Request model
# ------------------------------------------------------------------
class Request(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE, verbose_name='client')
project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='project')
product = models.ForeignKey(Subclass, on_delete=models.CASCADE, verbose_name='product')
category = models.ManyToManyField(Develop, verbose_name='category')
name = models.CharField('name', max_length=256, blank=True, null=True)
price = models.CharField('price', max_length=256, blank=True, null=True)
day = models.CharField('duedate', max_length=256, blank=True, null=True)
content = RichTextUploadingField('content', null=True)
file = models.FileField('file', upload_to=request_update_filename, blank=True, null=True)
created_at = models.DateTimeField('created_at', default=time)
add_meeting = models.BooleanField('add_meeting', default=False, null=True)
examine = models.BooleanField('check examing', default=False, null=True)
active_save = models.BooleanField('active-save', default=True, null=True)
class Meta:
verbose_name = ' request'
verbose_name_plural = ' requests'
def __str__(self):
return str(self.name)
class Answer(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE, verbose_name="client")
project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name="project", null=True)
partner = models.ForeignKey(Partner, on_delete=models.CASCADE, verbose_name="partner")
class Meta:
verbose_name = ' Answer'
verbose_name_plural = ' Answer'
def __str__(self):
return str(self.id)
and this is my admin code
#admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
inlines = [RequestInline,AnswerInline]
list_display = ['request_name','client_email','project_price','project_created','count_answer','count_meeting','answer_status']
def request_name(self, obj):
project_id = obj.id
request_name = Request.objects.get(project = project_id)
return request_name
def client_email(self, obj):
project_id = obj.id
client = Request.objects.get(project=project_id).client
return client
def client_phone(self, obj):
project_id = obj.id
client = Request.objects.get(project=project_id).client
phone = User.objects.get(username=client).phone
return phone
def project_price(self, obj):
project_id = obj.id
request_price = Request.objects.get(project=project_id).price
return request_price
def project_created(self, obj):
project_id = obj.id
created_at = Request.objects.get(project=project_id).created_at
return created_at
def count_answer(self, obj):
project_id = obj.id
answer_qs = Answer.objects.all()
answer = Answer.objects.filter(project=project_id)
count = len(answer)
return count
def count_meeting(self, obj):
project_id = obj.id
answer_yes = Answer.objects.filter(project = project_id, state = 1)
count = len(answer_yes)
return count
def answer_status(self, obj):
project_id = obj.id
answer = Answer.objects.filter(project = project_id, info_check =1)
count = len(answer)
return count
There are many factors not included in the above, but what I want to solve is not to bring in the same queryset(Request, Answer).
The project itself is a structure that does not have attributes but is received only by foreign keys. Such a structure is making it difficult to find a solution.
I used select_related(prefetch_related too), but it does not work.
If you can give me some advice, I'd like to take some advice. thanks.
p.s. It is my first time asking question on this site, I apologize if there was anything rude.
admin.TabularInline will show the reverse foreign key in the admin detail page that may help you, but it seems that you have already used it in the inlines of ProjectAdmin.

Django Models custom methods

is there any way to call a specific model custom method from a view? i need to subtract or increment depending on the view a field on my model, I want to create a button for each of the two options and after imputing that data update the field in my database. if so how can i go about implementing it, currently my save method is doing the two operations at once
models.py
class Items(models.Model):
nombre = models.CharField(max_length=250)
descripcion = models.CharField(max_length=250)
codigo_proveedor = models.CharField(max_length=250)
categoria = models.ForeignKey('Categorias', on_delete=models.CASCADE)
c_minima = models.PositiveIntegerField()
c_actual = models.PositiveIntegerField()
c_descuento = models.PositiveIntegerField(blank=True)
c_incremento = models.PositiveIntegerField(blank=True)
proveedor = models.ForeignKey('Proveedores', on_delete=models.CASCADE)
carrito = models.ForeignKey('Carrito', on_delete=models.CASCADE, null=True )
p_unitario = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True )
total = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
material = models.ForeignKey(Materiales, null=True, blank=True)
tipo = models.ForeignKey(Tipo, null=True, blank=True)
active = models.BooleanField()
def save(self, *args, **kwargs):
self.c_actual = self.c_actual - self.c_descuento
self.c_actual =self.c_actual + self.c_incremento
self.total = self.c_actual * self.p_unitario
super(Items, self).save(*args, **kwargs)
def __str__(self):
return '%s %s %s %s' % (self.nombre, str(self.categoria), str(self.c_actual), str(self.total))
You could use an instance method on the model e.g. exactly like the get_absolute_url().
You can add 3 methods in the model definition increment, decrement and total and write the respective logic in there.
So the view in the views.py file be something like
def some_view(request, *args, **kwargs):
#read the post data values from req
#create model instance
data = Items( #key value pairs)
#read from req to increament or decrement
if incr:
data.increament()
else:
data.decrement()
data.total()
data.save()
return render( ... )

Django 1.9.4 Filter many-to-one on 3 models with condition

I am trying to filter fields from three tables.
I need join 1 table as list and 2 table with condition.
I have Django 1.9.4, MySql 5.6.17
This is my models.py:
class Products(models.Model):
fullname = models.CharField(max_length=250, db_index=True)
code = models.CharField(max_length=15, db_index=True, null=True)
authors = models.CharField(max_length=300, db_index=True, null=True)
...
def __str__(self):
return self.fullname
class Barcodes(models.Model):
product = models.ForeignKey(Products, on_delete=models.CASCADE)
barcode = models.CharField(max_length=25, db_index=True, null=True)
def __str__(self):
return self.barcode
class Prices(models.Model):
product = models.ForeignKey(Products, on_delete=models.CASCADE)
price = models.FloatField(default=0)
shop_id = models.IntegerField(default=0)
shop_name = models.CharField(max_length=50, null=True)
def __str__(self):
return self.shop_name
I need get all Products, joined group_concat(distinct barcode) and joined price with shop_id = 1, if string in Prices not exist - return price = 0
I did so:
def get_queryset(self):
return Products.objects.values('id', 'fullname', 'authors', 'code', 'theme').annotate(barcodes=Concat('barcodes__barcode'))
And use aggregate function:
class Concat(Aggregate):
function = 'GROUP_CONCAT'
template = '%(function)s(%(distinct)s%(expressions)s)'
def __init__(self, expression, distinct=False, **extra):
super(Concat, self).__init__(
expression,
distinct='DISTINCT ' if distinct else '',
output_field=models.CharField(),
**extra)
How do I add Prices with shop_id = 1?
Thanks.
from django.db.models import Q
...
def get_queryset(self):
return Products.objects.filter(Q(prices__shop_id=1) | Q(prices__shop_id__isnull=True)).values('id', 'fullname', 'authors', 'code', 'tema', 'prices__price').annotate(barcodes=Concat('barcodes__barcode', True))