I have a model called Company. The Company could be the child of a bigger company. So in the model Company should be a attribute "parent" that is also a Company.
I got this:
class Company(models.Model):
name = models.CharField(max_length=250)
parent = models.ForeignKey(
Company,
on_delete=models.SET_NULL,
related_name="notification",
null=True,
blank=False,
)
But django is always saying I need to create a Company class. Is this the right way to do this?
Use 'self' keyword to reference the same model.
class Company(models.Model):
name = models.CharField(max_length=250)
parent = models.ForeignKey(
'self',
on_delete=models.SET_NULL,
related_name="notification",
null=True,
blank=False,
)
Related
I want to create on Abstract Model class for future inheriting like this:
class AbstractModel(models.Model):
created_at = models.DateTimeField(
auto_now_add=True,
blank=True,
null=True,
)
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
related_name='XXX_created_by',
blank=True,
null=True,
)
class Meta:
abstract = True
Field 'created_at' is working fine, but how to generate related_name in 'created_by' for my child classes to prevent clashing?
As the Be careful with related_name and related_query_name section of the documentation says, you can:
To work around this problem, when you are using related_name or related_query_name in an abstract base class (only), part of the value should contain '%(app_label)s' and '%(class)s'.
'%(class)s' is replaced by the lowercased name of the child class that the field is used in.
'%(app_label)s' is replaced by the lowercased name of the app the child class is contained within. Each installed application name must be unique and the model class names within each app must also be unique, therefore the resulting name will end up being different.
You thus can work with:
class AbstractModel(models.Model):
# …
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
related_name='%(class)s_created_by',
blank=True,
null=True,
)
class Meta:
abstract = True
Then the related_name will be foo_created_by if the name of the model that inherits is named foo.
Or if the same model name can occur in different apps:
class AbstractModel(models.Model):
# …
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
related_name='%(app_label)s_%(class)s_created_by',
blank=True,
null=True,
)
class Meta:
abstract = True
Then the related_name will be bar_foo_created_by if the name of the model that inherits is named foo in an app named bar.
I have 4 models: Products (the list of products: freezers, microwaves, tvs and pcs), ProductType (entertainment and home appliances), Credit (a credit is registered on each purchase) and PurchaseReason (the reason why the customer has bought the product).
The PurchaseReason depend on the productType, so the purchaseReason has a foreignKey field productType.
In addition, each credit has a product as foreignKey and a purchaseReason as foreignKey.
Also, I have the ProductReason field as a choice field in the credit model, and I want the options to be set dynamically based on the product field of the credit model.
I'm creating an API so I think this cant be handle with modelForms, but i'm not sure. The hard work would be with the serializers (DRF) and with the django-admin (specially this one because in my product the django admin plays an important role)
What would be the best approach to manage my models in Django?
Here are my models. In credit I'm not sure how to implemente the purchase reason:
class Credit(models.Model):
client = models.ForeignKey('clients.Client', on_delete=models.SET_NULL)
name = models.CharField(max_length=30, null=False, blank=True)
product = models.ForeignKey('product',on_delete=models.SET_NULL)
reason_purchase = models.ChoiceField(????)
class PurchaseReason(models.Model):
product_type = models.ForeignKey(product_type, on_delete=models.CASCADE)
reason = models.CharField(max_length=30, null=False, blank=True)
class ProductType(models.Model):
name = models.CharField(max_length=30, null=False, blank=False)
class Product(models.Model):
model = models.CharField(max_length=30, default=None, null=True)
product_type = models.ForeignKey(product_type, on_delete=models.CASCADE)
When we use the foreign key, we need to mention the model name of that particular model so that we can integrate that particular model in that model as a reference entity. Have a look at this example.
from django.db import models
class Reporter(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
def __str__(self):
return "%s %s" % (self.first_name, self.last_name)
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
def __str__(self):
return self.headline
class Meta:
ordering = ['headline']
you've not mentioned the model name properly. it should be Product in place of 'product' in the Credit class, product field.
use this reference https://docs.djangoproject.com/en/3.2/topics/db/examples/many_to_one/
i think you should be able to use the Foreignkey field properly after this. Although, if you can't, you can share the actual objective. i will help you to write the correct model.
Best wishes :)
I need to model a many to many relationship.
I've read some documentation, but I don't know how to model.
I'll give you an example of what I want to do.
I have two entities, Album and song.
They have a many to many relationship.
class Song(models.Model):
name = models.CharField(unique=True, max_length=255)
class Album(models.Model):
nombre = models.CharField(unique=True, max_length=255)
songs = models.ManyToManyField(Song, blank=True)
The user in the frontend, provides me the data of an album that I must save.
It provides me the name of the album and the name of the songs.
How could I model it on the serializers?
Nothing runs.
I think you can delete that blank=True i think it automatically can be blank.
class Song(models.Model):
name = models.CharField(unique=True, max_length=255)
class Album(models.Model):
nombre = models.CharField(unique=True, max_length=255)
songs = models.ManyToManyField(Song, related_name='songs', blank=True)
and you can make the serializer.
Django will create a table for many to many relationships. You can do this by yourself as well with customized fields. For example, you may like to save the order for songs in an album:
class Song(models.Model):
name = models.CharField(unique=True, max_length=255)
class Album(models.Model):
name = models.CharField(unique=True, max_length=255)
class AlbumSong(models.Model):
album = models.ForeignKey('Album', null=False, on_delete=models.PROTECT)
song = models.ForeignKey('Song', null=False, on_delete=models.PROTECT)
order = models.PositiveIntegerField(null=False)
removed = Bit1BooleanField(null=False, default=False)
How to make a one to many relationship in Django/Mysql?
I have an identical situation to this post, yet, my django returns errors on the admin page:
get() returned more than one order2pizza-- it returned 5!
order2pizza with that pizza already exists.
My mysql database have composite keys on a tertiary table to order and pizza to link multiple pizzas to an order.
models.py:
class Orders(models.Model):
order_id = models.AutoField(primary_key=True)
order_name = models.CharField(max_length=100, blank=True, null=True)
class Pizza(models.Model):
Pizza= models.AutoField(primary_key=True)
Pizza_name= models.CharField(max_length=50, blank=True, null=True)
class order2pizza(models.Model):
order = models.ManyToManyField(Orders, models.DO_NOTHING, )
pizza_id= models.IntegerField()
class Meta:
unique_together = (('order ', 'pizza_id'),)
A many-to-many relation can be expressed in two ways. First, you can manually specify a "join" model, like this:
class Orders(models.Model):
order_name = models.CharField(max_length=255, blank=True)
class Pizza(models.Model):
Pizza_name= models.CharField(max_length=255, blank=True)
class Order2Pizza(models.Model):
order = models.ForeignKey(Order, models.CASCADE)
pizza = models.ForeignKey(Pizza, models.CASCADE)
class Meta:
unique_together = ['order ', 'pizza']
This is useful if you want to put extra fields on the Order2Pizza model. A field named quantity would be very useful in your example.
The second option is to use a ManyToManyField. This will automatically create the join model for you:
class Orders(models.Model):
order_name = models.CharField(max_length=255, blank=True)
pizzas = models.ManyToManyField('Pizza', related_name='orders')
class Pizza(models.Model):
Pizza_name= models.CharField(max_length=255, blank=True)
In your original question you put the ManyToManyField on the Order2Pizza model, which is nonsensical.
However, the source of your bug is probably your manual inclusion of several *_id fields. Don't do that. They will always be created automatically by Django and you should never have to specify them manually. Instead, try the two options above and see how they work.
I have this two models:
class Folder(MPTTModel):
name = models.CharField(max_length=20)
description = models.CharField(max_length=200, null=True, blank=True)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
position = models.IntegerField(default=0)
class MPTTMeta:
order_insertion_by = ['position']
class Page(MPTTModel):
title = models.CharField(max_length=50)
file_content = models.TextField()
parent = TreeForeignKey(Folder, null=False, blank=False, related_name='page', on_delete=models.CASCADE)
I have been trying and trying, but I can't find any solution.
Is there anyway to merge those two models in just one tree diagram?
The idea is that a Folder can contain a Folder or a Page
I'm using django 1.6.5 and python3
Maybe you should create an abstract superclass. Then you can have this class from which both (folder and Page) inherit and you can define the parent relation already in there.