Is it good database design? - django

I have this task to create api:
City district - name, id
Category - name, id
Organization Network - name, id
Organization
Belongs to one of the organization networks
id, name, description
belongs to several districts, can be represented in several of them at the same time
have list of products with prices
Product
id, name, category
can be sold in one or several organizations in network
price can be different depending on the organization
This is my try to design this database, am I missing something?
And also in Django:
from django.db import models
class District(models.Model):
name = models.CharField(max_length=100, unique=True)
class Category(models.Model):
name = models.CharField(max_length=100, unique=True)
class OrganizationNetwork(models.Model):
name = models.CharField(max_length=100, unique=True)
class Organization(models.Model):
name = models.CharField(max_length=100, unique=True)
description = models.TextField()
organization_network = models.ForeignKey(
OrganizationNetwork,
on_delete=models.CASCADE,
related_name="organizations",
)
district = models.ManyToManyField(
"District",
through="DistrictOrganization",
through_fields=("organization", "district"),
related_name="organizations",
)
products = models.ManyToManyField(
"Product",
through="OrganizationProduct",
through_fields=("organization", "product"),
related_name="organizations",
)
class Product(models.Model):
name = models.CharField(max_length=100, unique=True)
category = models.ForeignKey(
Category, on_delete=models.CASCADE, related_name="products"
)
class DistrictOrganization(models.Model):
district = models.ForeignKey(District, on_delete=models.CASCADE)
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
class OrganizationProduct(models.Model):
price = models.DecimalField(max_digits=10, decimal_places=2)
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)

It`s pretty strange to create 2 relations between organization and district. You should use one to many if there could be only one organization in district, many to many otherwise.

Related

django foreign key filtering in admin panel

class City(models.Model):
name = models.CharField(max_length=200, null=True, blank=False)
class District(models.Model):
city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200, null=True, blank=False)
class ShippingAddress(models.Model):
city = models.ForeignKey(City, on_delete=models.CASCADE, null=False)
district = models.ForeignKey(District, on_delete=models.CASCADE, null=False)
I would like to filter the admin panel by city (selected city). in order to filter too much similar districts names.
If someone has another way to do it no problem, that was a junior try, waiting for your advice.

I wanna overrite the admin page

In the admin page when I create a property first I want to have a dropdown when I can choose the city and then another dropdown when I can choose a district where there are Districts that have ForeignKey key the city I selected
class City(models.Model):
name = models.CharField(verbose_name="Emri", help_text="E nevojshme", max_length=255, unique=True)
...
class District(models.Model):
city_id = models.ForeignKey(City, on_delete=models.CASCADE)
name = models.CharField(verbose_name="Emri", help_text="E nevojshme", max_length=255, unique=True)
...
class Property(models.Model):
district_id = models.ForeignKey(District, on_delete=models.CASCADE)
...

Django: handle multi stock (related table) in Product Based List View

I need to manage Products shared by multiple Warehouses.
I tried to get through with annotate, prefetch_related, select_related but in my case, those solutions are upside-down for my need. I need first to get product and then, the related stock in each warehouse and display it in template and the foreignKey is in my Sststock, not in Product
I have :
Product models.py
class Product(models.Model):
famille = models.ForeignKey(Famille, on_delete=SET_NULL, null=True)
sku = models.CharField(max_length=100, unique=True)
nom = models.CharField(max_length=250)
fournisseur = models.ForeignKey(
Supplier, on_delete=models.SET_NULL, default=12, null=True)
qty = models.IntegerField()
mini = models.IntegerField()
maxi = models.IntegerField()
[...]
Warehouse models.py
class Warehouse(models.Model):
nom = models.CharField(max_length=100)
code = models.CharField(max_length=10, null=True)
adresse = models.CharField(max_length=255)
cp = models.IntegerField()
ville = models.CharField(max_length=50)
tel = models.CharField(max_length=10)
email = models.EmailField(default='sav#iturbo.fr', null=False, blank=False)
allow_store = models.BooleanField(default=False)
def __str__(self):
return self.nom.upper()
Sststock models.py
class SstStock(models.Model):
sst = models.ForeignKey(Warehouse, on_delete=models.CASCADE)
mageid = models.ForeignKey(Product, on_delete=models.CASCADE, null=True)
qty = models.IntegerField()
last_update = models.DateTimeField(default=timezone.now)
For the time, I only have 3 warehouses but there could have more in the future.
First I had "hard-coded" my 3 warehouses in Product's model but this solution was not easily scalable.
What would be the best way to achieve my goal ?
I've seen solution with Mysql Stored Procedures in PhpMyAdmin for creating innerJoin tables but there is maybe possibilities within Django.

Django admin - Filter foreignKey in an Inline

I have these models:
class Country(models.Model):
name = models.CharField(unique=True, max_length=50)
class Person(models.Model):
name = models.CharField(max_length=50, blank=True, null=True)
country = models.ForeignKey(Country, models.DO_NOTHING, db_column='countries', blank=True, null=True)
class Organization(models.Model):
name = models.CharField(max_length=50, blank=True, null=True)
class Membership(models.Model):
person= models.ForeignKey(Person, models.DO_NOTHING, db_column='people', blank=True, null=True)
organization= models.ForeignKey(Organization, models.DO_NOTHING, db_column='organizations', blank=True, null=True)
There are a high number of people (over 1000) that can be members of several organizations.
I have a view in the admin page as follows
class MembershipInline(admin.StackedInline ):
model = Membership
extra = 1
class OrganizationAdmin(admin.ModelAdmin):
inlines = [MembershipInline]
admin.site.register(Organization,OrganizationAdmin)
Therefore I can manage any organization and see the people that belongs to it. I can also add new people to the organization.
The problem is that the number of people is too high and the list shows too many of them. Is there any way to filter this StackedInline?
For example placing another field in the Inline where a country can be chosen to filter the people that can be added, or a search field to filter the person's name.
Thanks in advance!
Finally got to work using the option "autocomplete_fields "
class PersonAdmin(admin.ModelAdmin):
search_fields = ['country__name','name']
admin.site.register(Person,PersonAdmin)
class MembershipInline(admin.StackedInline ):
model = Membership
extra = 1
autocomplete_fields = ['person',]
How it looks

Custom ORM in Django. Based on Entity ID & Entity Type

My aim is to retrieve data from different model with the reference of entity type & entity id.
Example:
I have Customer model & Address model
from django.db import models
class Customer(models.Model):
name = models.CharField(null=False, blank=False, max_length=255)
email = models.EmailField(null=False, blank=False, unique=True)
class Address(models.Model):
entity_type = models.CharField(null=False, max_length=255)
entity_id = models.PositiveIntegerField(null=False)
address1 = models.CharField(max_length=255)
address2 = models.CharField(max_length=255)
for now i using raw query
cursor.execute("SELECT * FROM customers AS cust
INNER JOIN addresses AS addrs ON
(cust.id = addrs.entity_id AND 'customer' = addrs.entity_type)
WHERE cust.id IN (%s)", [ids])
But this is not Good solution. Take too much time when ids is in thousands of range.
If is there any other way to archive those data. Then please give your solution in comments..
It seems awkward to manage an ID to an external entity with an "entity_id" field. Why not use a ForeignKey field to a Customer, or in case the entity is not always a Customer, use a GenericForeignKey ?
Right now you are reinventing the wheel.
class Address(models.Model):
entity_type = models.CharField(null=False, max_length=255)
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL)
Then:
q = Address.objects.filter(customer in cutomers_collection)
The doc about ForeignKey: https://docs.djangoproject.com/en/3.0/ref/models/fields/#django.db.models.ForeignKey
query_set = Address.objects.filter(
Q(entity_type='R') | Q(entity_id=1)
)
from django.db import models
class Customer(models.Model):
name = models.CharField(null=False, blank=False, max_length=255)
email = models.EmailField(null=False, blank=False, unique=True)
class Address(models.Model):
entity_type = models.CharField(null=False, max_length=255)
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL)
address1 = models.CharField(max_length=255)
address2 = models.CharField(max_length=255)
data = Address.objects.filter(entity_type='customer', customer_id__in=[ids]).values('address1', 'address2', 'customer__name', 'customer__email')