Django: Reference between models - python

Help!
I have the following 2 models:
class Account(models.Model):
username = models.OneToOneField(User, primary_key=True, unique=True)
receiveaddress = models.CharField(max_length=40, blank=True, null=True, unique=True)
balance = models.DecimalField(max_digits=16, decimal_places=8, default=0)
def __str__(self):
return str(self.username)
class Deposits(models.Model):
receiveaddress = models.CharField(max_length=40, blank=True, null=True, unique=True)
amount = models.DecimalField(max_digits=16, decimal_places=8, default=0)
user = ?????????????????
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
confirmed = models.BooleanField(default=False)
accounted = models.BooleanField(default=False)
def __str__(self):
return str(self.receiveaddress)
Example:
Visualization
My problem:
I want "Deposits.user" to automatically reference the user to which this 'receiveaddress' belongs. In the example, that's TIM. I've wasted 6 hours trying to figure it out, what am I doing wrong?
Thanks in advance.

I think it' just a design matter. Why do you put two fields that have the same information, since the user has account with receiveaddress, adding the user as foreign key will be enough and cleaner, I suggest the following:
class Account(models.Model):
username = models.OneToOneField(User, primary_key=True, unique=True)
receiveaddress = models.CharField(max_length=40, blank=True, null=True, unique=True)
balance = models.DecimalField(max_digits=16, decimal_places=8, default=0)
def __str__(self):
return str(self.username)
class Deposit(models.Model):
amount = models.DecimalField(max_digits=16, decimal_places=8, default=0)
user = models.ForeignKey(User, related_name="deposits")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
confirmed = models.BooleanField(default=False)
accounted = models.BooleanField(default=False)
def __str__(self):
return str(self.user.account.receiveaddress)
NB: As a convention, models name should be always singular

Related

Django Relational managers

I was trying to delete my Apllication model:
class Application(models.Model):
app_type = models.ForeignKey(ApplicationCategory, on_delete=models.CASCADE, related_name='applications')
fio = models.CharField(max_length=40)
phone_number = models.CharField(max_length=90)
organisation_name = models.CharField(max_length=100, null=True, blank=True)
aid_amount = models.PositiveIntegerField()
pay_type = models.CharField(max_length=1, choices=PAY_CHOICES, default=PAY_CHOICES[0][0])
status = models.ForeignKey(AppStatus, on_delete=models.CASCADE, related_name='applications', null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
benefactor = models.ForeignKey(Benefactor, on_delete=models.CASCADE, related_name='applications', null=True)
def __str__(self):
return f"id={self.id} li {self.fio} ning mablag\'i!"
and this was my Benefactor model:
class Benefactor(models.Model):
fio = models.CharField(max_length=255)
phone_number = models.CharField(max_length=9)
image = models.ImageField(upload_to='media/')
sponsory_money = models.IntegerField()
organisation_name = models.CharField(max_length=55, null=True, blank=True)
def __str__(self):
return f"{self.fio}"
But I got the below message on superAdmin Panel:
TypeError at /admin/api/benefactor/
create_reverse_many_to_one_manager.\<locals\>.RelatedManager.__call__() missing 1 required keyword-only argument: 'manager'
I would expect delete smoothly!!
Your Benefactor model has several ForeignKey relationships that share the related_name. Give each a unique name and rerun your migrations.

Django: saving unique value without duplicate it

I'm trying to save unique name in the database but the problem I can save the same with different letters, for example I can save (IT, it, iT, It) I don't want to save it like that.
Model:
class Service(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=127, unique=True, null=False, blank=False) # that field
is_active = models.BooleanField(default=True)
is_deleted = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(
"accounts.User",
on_delete=SET_NULL,
blank=False,
null=True,
related_name="service_created_by",
)
def __str__(self):
return f"{self.name}"
A very simple solution:
class Service(models.Model):
name = models.CharField(max_length=50, unique=True)
....
def clean(self):
self.name = self.name.capitalize()
this one helped me
class Service(models.Model):
name = models.CharField(max_length=50, unique=True, null=False, blank=False)
....
class Meta:
constraints = [
models.UniqueConstraint(Lower("name"), name="unique_name"),
]
def clean(self):
self.name = self.name.capitalize()

Cannot assign "'Sample Category'": "Product.category" must be a "Category" instance

While creating new products I'm getting such kind of error. Can someone help me?
class Product(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
name_geo = models.CharField(max_length=200, null=True, blank=True)
image = models.ImageField(null=True, blank=True, default='/placeholder.png')
brand = models.CharField(max_length=200, null=True, blank=True)
category = models.ForeignKey(Category, null=False, default=0, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True)
countInStock = models.IntegerField(null=True, blank=True, default=0)
createdAt = models.DateTimeField(auto_now_add=True)
_id = models.AutoField(primary_key=True, editable=False)
def __str__(self):
return self.name_geo
class Category(models.Model):
_id = models.AutoField(primary_key=True, editable=False)
name = models.CharField(max_length=200, null=True, blank=True)
createdAt = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
#api_view(['POST'])
def createProduct(request):
user = request.user
product = Product.objects.create(
user=user,
name_geo="Sample Name",
category="Sample Category",
price=0,
brand='Sample Brand',
countInStock=0,
)
serializer = ProductSerializer(product, many=False)
return Response(serializer.data)
Without separating category class in models.py everything works fine. I mean If i didn't use ForeignKey in Products class for category
It just has to be a Category Instance/Object
product = Product.objects.create(
user=user,
name_geo="Sample Name",
category=Category.objects.get_or_create(name="Sample Category"),
price=0,
brand='Sample Brand',
countInStock=0,
)
Notes:
You could just do a .get() or a .filter().first() if you don't want to create
If you use a form, you can get away with just the Category's PK/_id in the POST
this type of thing: f = form(request.POST) f.is_valid() f.save()
At the end that field will hold the PK/_id/Row# of the Category Obj

Getting a field from another django model?

How can I get the field pto from emplyees app and use it in the permission app.
employee/models.py
class Employee(AbstractUser):
department = models.ForeignKey(Department, on_delete=models.CASCADE,blank=True, null=True)
pto = models.IntegerField(default=20)
is_deleted = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
roles = models.ManyToManyField(Role, related_name='+')
def __str__(self):
return self.username
permission/models.py
class Permission(models.Model):
STATUS = (
('PENDING', 'PENDING'),
('DENIED', 'DENIED'),
('ACCEPTED', 'ACCEPTED')
)
user = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='lorem')
description = models.CharField(max_length=255)
date_created = models.DateTimeField(auto_now=True, blank=True, null=True)
date = models.DateField()
status = models.CharField(max_length=200, choices=STATUS, default=STATUS[0][0])
is_deleted = models.BooleanField(default=False)
def __str__(self):
return self.description
sorry if a was not clear, thanks in advance
add this to class Permissions model
from yourproject.apps.employee.models import Employee
class Permission(models.Model):
..........
def get_pto(self):
return int(self.user.pto) # if it's floating point number then change int to float
now you can use get_pto in your html, {{ form.get_pto }}
Sorry if this is not what you are looking for, let me know clearly and I will try to answer if I can.

Is a self-join on a model in a django app an acceptable pattern?

Apologies if this question is too subjective.
If you are planning to close this question: please comment with a suggestion for a more appropriate place to post.
I'm super new to django and python, and I'm building a test app that keeps track of employees and who their managers are.
I would like to set up the domain model so that there there is only one list of employees, any of which can be managers, and all of which can be managed by any other employee who is designated a manager.
To achieve this, I did a self-join on the Employee model and have an "is_manager" flag to keep track of who is a manager and who isn't (see model below).
Is an acceptable pattern?
I'm worried it violates a design principle I'm not considering and there's some hairy trap that I'm walking into as a noob.
Thank you very much for your time.
models.py for the app:
class OrganizationTitle(models.Model):
def __str__(self):
return "{}".format(self.organization_title_name)
organization_title_name = models.CharField(max_length=150, unique=True)
class ClassificationTitle(models.Model):
def __str__(self):
return "{}".format(self.classification_title_name)
classification_title_name = models.CharField(max_length=150, unique=True)
class WorkingTitle(models.Model):
def __str__(self):
return "{}".format(self.working_title_name)
working_title_name = models.CharField(max_length=150, unique=True)
class Category(models.Model):
def __str__(self):
return "{}".format(self.category_name)
category_name = models.CharField(max_length=150, unique=True)
class Department(models.Model):
def __str__(self):
return "{}".format(self.department_name)
department_name = models.CharField(max_length=150, unique=True)
class Employee(models.Model):
first_name = models.CharField(max_length=150)
last_name = models.CharField(max_length=150)
org_title = models.ForeignKey(OrganizationTitle, blank=True, null=True, on_delete=models.SET_NULL)
manager = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL)
manager_email = models.EmailField(max_length=50, blank=True, null=True)
hire_date = models.DateField(blank=True, null=True)
classification_title = models.ForeignKey(ClassificationTitle, blank=True, null=True, on_delete=models.SET_NULL)
working_title = models.ForeignKey(WorkingTitle, blank=True, null=True, on_delete=models.SET_NULL)
email_address = models.EmailField(max_length=250, blank=False, unique=True,
error_messages={'unique': 'An account with this email exist.',
'required': 'Please provide an email address.'})
category = models.ForeignKey(Category, blank=True, null=True, on_delete=models.SET_NULL)
is_substitute = models.BooleanField(default=False)
department = models.ForeignKey(Department, blank=True, null=True, on_delete=models.SET_NULL)
is_active = models.BooleanField(default=True)
is_manager = models.BooleanField(default=False)
class Meta:
ordering = ('is_active', 'last_name',)
def __str__(self):
return "{}".format(self.first_name + ' ' + self.last_name)
That's perfectly fine.
I would recommend you to specify the related_name to keep your code more explicit:
manager = models.ForeignKey(..., related_name="managed_employees")
so then you can do something like:
bob.managed_employees.all()
Also, there are 2 things I would change (not your question but still regarding the models):
1.The manager_email field is redundant. I would remove it. You already have that information at tom.manager.email_address for example.
2.There are many fields that I would simply rename to name. For example:
class OrganizationTitle(models.Model):
def __str__(self):
return u"{}".format(self.name)
name = models.CharField(max_length=150, unique=True)
No need to call it organization_title_name. That's consistent with the first_name field (not employee_first_name).
Yes, this is an acceptable pattern. This is called a "recursive relationship", or "self referential foreign keys" and is a very common usecase in realworld applications.
Here is django's example supporting this usecase

Categories