The use case of my application is I will have various fields to fill and among them one is Industry field and another is Segment Field for brand. The industry field is like category that brand falls into. So, if i choose the industry as Health Care for XYZ brand then the segment field should show the items like 'Ayurveda', 'Dental Clinics' (all health care related items). Basically, its like sub-category.
Here is a sample model
class Industry(models.Model):
name = models.CharField(max_length=150, blank=True, null=True)
class Meta:
verbose_name = 'Industry'
verbose_name_plural = 'Industries'
def __str__(self):
return self.name
class Segment(models.Model):
industry = models.ForeignKey(Industry, related_name='segment', on_delete=models.CASCADE)
name = models.CharField(max_length=150, blank=True, null=True)
class Meta:
verbose_name = 'Segment'
verbose_name_plural = 'Segments'
def __str__(self):
return f'{self.industry.name} - {self.name}'
class BusinessModel(models):
industry = models.ForeignKey(Industry, blank=False, null=False, related_name='industry', on_delete=models.CASCADE)
# segements = models.ForeignKey()
total_investment = models.CharField() # will be choice field
This is a simple model and I have not created Segment model as I am not sure how to approach to this problem. I am just curios to know, if for such case, do i have to something special in models.py or in the view side. Such type of things get arise during development phase, thus, I want to be clear on problem solving pattern in django.
UPDATE
https://www.franchisebazar.com/franchisor-registration here if you choose industry inside Business model section, the segment will be updated accordingly.
You can have a 3 model design like
class Industry(models.Model):
name = models.CharField(max_length=150, blank=True, null=True)
class Segment(models.Model):
name = models.CharField(max_length=150, blank=True, null=True)
class Mapping(models.Model):
industry = models.ForeignKey(Industry)
segment = models.ForeignKey(Segment)
You need to define relations between your models. You can find documentation about ManyToMany relation here which is suitable in your case.
you can use ChainedForeginKey.. Check the below links
customizing admin of django to have dependent select fields
https://django-smart-selects.readthedocs.io/en/latest/installation.html
Related
I am new in django and trying to create a website where I can search for vehicles and see what parts I have for this vehicle.
I have two databases, one with vehicles and one with parts:
class Vehicle(models.Model):
vehicle_id = models.BigIntegerField(primary_key=True)
vehicle = models.CharField(max_length=255)
def __str__(self):
return self.vehicle
class Part(models.Model):
part_id = models.BigIntegerField(primary_key=True, db_column='part_id')
part_name = models.CharField(max_length=255, db_index=True, null=True)
catalog_code = models.CharField(max_length=255, null=True)
price = models.CharField(max_length=255, default=None, null=True)
description = models.CharField(max_length=255, default=None, null=True)
vehicle_id = models.ForeignKey(Vehicle, on_delete=models.PROTECT, null=True)
def __str__(self):
return self.part_name
Now I using oneToMany, but can't figure out if it is correct and how can I see all parts for one vehicle
You implemented the relationship correctly. One to many is a way to go here.
You can make your life easier by defining related_name in the ForeighKey:
vehicle_id = models.ForeignKey(Vehicle, on_delete=models.PROTECT, null=True, related_name="parts")
and use the following constructs when referring to the vehicle parts:
myvehicle.parts.all()
myvehicle.parts.filter(part__part_id=1)
Side comment: I do not think that it was a good idea to define id fields explicitly. Django sets model id fields automatically (and defines them as primary keys).
Is there a way to refer to specific object of Model? Suppose I have some models like below:
# models.py
class VehicleCategoryCode(models.Model):
category = models.CharField(max_length=5)
name = models.CharField(max_length=20)
class Code(models.Model):
category = models.ForeignKey(VehicleCategoryCode, on_delete=models.CASCADE)
index = models.CharField(max_length=4, blank=True)
label = models.CharField(max_length=50)
order = models.CharField(max_length=20, blank=True)
is_active = models.BooleanField(default=True)
# pay attention to the Model
class Vehicle(models.Model):
label = models.CharField(max_length=80)
model = models.CharField(max_length=30)
Currently Vehicle is not linked to any model.
Now Code model is ForeignKey to VehicleCategoryCode, which has two objects. In the VehicleCategoryCode the first object label (for convenience sake) will be referenced by Vehicle.label, and the second object model (once again for convenience) will be referenced by Vehicle.model. So each field in Vehicle can refer to the same model, but different objects.
So basically I'm wondering if something like the pseudo code below can be achieved anyhow.
class Vehicle(models.Model):
label = models.ForeignKey(VehicleCategoryCode__name='label', on_delete=models.CASCADE)
model = models.ForeignKey(VehicleCategoryCOde__name='model', on_delete=models.CASCADE)
Any suggestion or advice would be appreciated. Thank you.
You can make use of the limit_choices_to=… parameter [Django-doc]:
Vehicle(models.Model):
label = models.ForeignKey(
Code,
limit_choices_to={'category__name': 'label'},
on_delete=models.CASCADE
)
model = models.ForeignKey(
Code,
limit_choices_to={'category__name': 'model'},
on_delete=models.CASCADE
)
For ModelForms and in the ModelAdmin it will limit the choices, note however that tese are not enforced by the database.
I am struggling with Many-to-Many model and form. What is the best way to show extra level field when creating a new Person with skill. I am going also to edit it later.
I am trying to achieve an effect in forms like that:
[input text] name
[select] skill name (there are choices in the model)
[input text] level of the skill
I tried things which people were suggesting but I couldn't make it to work. For example inlineformset + through.
Later on, I would like also to give the user a chance to add multiple sets of skill+level, maybe it is worth to think about it in advance?
My models and form:
class PersonSkill(models.Model):
person = models.ForeignKey('Person', on_delete=models.CASCADE)
skill = models.ForeignKey('Skill', on_delete=models.CASCADE)
level = models.CharField(max_length=50, choices=[(1, 'working'),
(2, 'advanced'),
(3, 'champion')], null=True, blank=True)
class Skill(models.Model):
name = models.CharField(max_length=50, null=True, blank=True)
def __str__(self):
return self.name
class Person(models.Model):
name = models.CharField(max_length=30, null=True, blank=True)
skill = models.ManyToManyField('Skill', through='PersonSkill', blank=True)
def __str__(self):
return self.name
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ('name',)
In my project there is an Attraction model and an AttractionTag model related through a ForeignKey relationship. Every Attraction has the same set of AttractionTag, they differ only by the value field.
Now, I want to order Attractions based on the value field of a specific AttractionTag. For example, there is an AttractionTag named 'modern' for every attraction. I want to order Attractions based on modern AttractionTag value field.
I've tried
attractions.order_by('-attractiontag__value')
but this command order Attractions on AttractionTag in general, not based on a particular AttractionTag.
Here are the models
class Attraction (models.Model) :
city = models.ForeignKey(City, on_delete=models.CASCADE)
name=models.CharField(max_length=50, unique=True)
image = models.ImageField(upload_to=attractionImagePath, null=True, blank=False)
imageTop = models.ImageField(upload_to=attractionTopImagePath, null=True, blank=True)
pub_date = models.DateTimeField(auto_now_add=True)
class AttractionTag (models.Model):
attraction=models.ForeignKey(Attraction, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
value=models.IntegerField(default=0)
How can I solve?
Thank you
Ok, I found a solution.
tags = AttractionTag.objects.filter(attraction__city=city)
tags = tags.filter(name='modern').order_by('-value')
attraction = [tag.attraction for tag in tags]
Should work
I have three models so far:
class clientCode(models.Model):
unique_id = models.CharField(max_length=9, blank=False)
def __str__(self):
return self.unique_id
class clientAccount(models.Model):
clientCode = models.ForeignKey(ClientCode,
on_delete=models.CASCADE, related_name='clientBusiness',null=True)
clientAccount = models.CharField(max_length=13, blank=False)
clientName = models.CharField(max_length=45, blank=False)
class assets(models.Model):
assetName = models.CharField(max_length=45, blank=False)
assetCurrency = models.CharField(max_length=45, blank=False)
assetCode = models.CharField(max_length=15, blank=False)
def __str__(self):
return self.assetName
Now, I would like to have a model containing ALL the fields from the above + an amount and transaction.
I started as so...
class Holdings(models.Model):
holdingsName = models.ManyToManyField(assets)
The issue is this, while this returns the assetName which is what I'd like, how do I retrieve the assetCurrency?
I guess I need to know: How do I reference an individual field from one model another model?
I am truly lost on how to do this, i've tried various ForeignKey, ManytoMany.. Is the correct approach to build a form that includes all the fields and posts to said model?
To clarify, I would essentially like clientAccount and assets to remain as lists, and the Holdings model fields to be dropdowns relating to these models?
Sorry if this is unclear and thanks in advance for any help! - I'm sure Ive got the wrong end of the stick on how to build the models.
Ok you need to first of all determine how are your models related to each other or what are the relationships between ClientCode, ClientAccount, Assets and Holdings.
As an example, loosely defined holdings are stocks, property or other finanical assets in someone's possesion. So your models for holdings and assets could be something like that.
Also please follow the Django Naming Conventions for your code. I have changed field/model names to reflect that below. Link here
class Asset(models.Model)
asset_name = models.CharField(max_length=45, blank=False)
asset_currency = models.CharField(max_length=45, blank=False)
asset_code = models.CharField(max_length=15, blank=False)
def __str__(self):
return self.asset_name
class Holding(models.Model)
holding_name = models.CharField(max_length=50)
assets = models.ManyToManyField(Asset, related_name='holdings',
through='HoldingAsset')# if you want some more explicit fields on the through model
def __str__(self):
assets = self.assets.all()
asset_currencies = [asset.asset_currency for asset in assets]
return '%s -- %s' % (self.holding_name, self.asset_currencies)
Now if you get a holding object like this (ignoring any unhandled errors here)
holding = models.Holding.objects.get(holding_name='Test_Holdings')
to access your assets and their currencies , you could do something like this.
assets = holding.assets.all()
asset_currencies = [asset.asset_currency for asset in assets]
To load holdings based on assets, or vice-versa, you will need to use modelforms and use a chained drop-down approach.