How to use #property in Django models? - django

I want to add one subquery to my query. And I created a #property in Transaction. Found on the Internet that this is what I need. But I do not fully understand how they work. How to use it?
views.py(Query)
paymentsss = Transaction.objects.all().select_related('currency',
'payment_source__payment_type',
'deal__service__contractor',).
models.py
class PayerPaymentSource(models.Model):
id = models.BigIntegerField(blank=True, null=False, primary_key=True)
payer_id = models.BigIntegerField(blank=True, null=True)
payment_type = models.ForeignKey(PaymentType, max_length=64, blank=True, null=True, on_delete=models.CASCADE)
source_details = models.TextField(blank=True, null=True) # This field type is a guess.
class Meta:
managed = False
db_table = '"processing"."payer_payment_source"'
class Transaction(models.Model):
id = models.BigIntegerField(blank=True, null=False, primary_key=True)
currency = models.ForeignKey(Currency, null=True, on_delete=models.CASCADE)
deal = models.ForeignKey(Deal, null=True, on_delete=models.CASCADE)
# service_instance = models.ForeignKey(ServiceInstance, null=True, on_delete=models.CASCADE)
payment_source = models.ForeignKey(PayerPaymentSource, null=True, on_delete=models.CASCADE)
payment_date = models.DateTimeField(blank=True, null=True)
amount = models.IntegerField(blank=True, null=True)
status = models.CharField(max_length=255, blank=True, null=True)
context = models.TextField(blank=True, null=True)
#property
def bank_card_details(self):
return PayerPaymentSource.objects.filter(self.payment_source.source_details,
payment_type='bank_card_details')
class Meta:
managed = False
db_table = '"processing"."transaction"'
UPD: print(payment.bank_card_details) works, but it creates a lot of similar queries. How to fix it?

The #property decorator is just a convenient way to call the property() function, which is built in to Python. This function returns a special descriptor object which allows direct access to the method's computed value.
For example in your view
obj = Transaction.objects.get(pk=pk)
#now you can get the bank_card_details like this:
print(obj.bank_card_details)

Related

possible to split the model based on field in DRF admin.py

I have model named organization. I am using this same model model for 2 api's. I have a field code. one API do code auto generation another API takes user entry code. I want to separate the tables based on code. Autogeneration code starts SUB001,SUB002,.... like wise. user entry code thats userwish.
models.py
class Organization(models.Model):
code = models.CharField(max_length=255, null=False, unique=True)
name = models.CharField(max_length=255, null=False)
organization_type = models.CharField(max_length=255, choices=TYPES, null=False, default=COMPANY)
internal_organization = models.BooleanField(null=False, default=True)
location = models.ForeignKey(Location, on_delete=models.RESTRICT)
mol_number = models.CharField(max_length=255, null=True, blank=True)
corporate_id = models.CharField(max_length=255, null=True, blank=True)
corporate_name = models.CharField(max_length=255, null=True, blank=True)
routing_code = models.CharField(max_length=255, null=True, blank=True)
iban = models.CharField(max_length=255, null=True, blank=True)
description = models.TextField(null=True, blank=True)
total_of_visas = models.IntegerField(null=False, default=0)
base_currency = models.ForeignKey(Currency, on_delete=models.RESTRICT, null=True, blank=True, default=None)
logo_filename = models.ImageField(_("Image"), upload_to=upload_to, null=True, blank=True)
def __str__(self):
return self.name
admin.py
#admin.register(Organization)
class OrganizationAdmin(admin.ModelAdmin):
list_display = (
'id',
'code',
'name',
'location',
'organization_type',
'internal_organization',
'mol_number',
'corporate_id',
'corporate_name',
'routing_code',
'iban',
'description',
'total_of_visas',
'base_currency',
'logo_filename',
)
Is there any possible to split models based on code,.. Really Expecting help...
You can use Proxymodel inheritance. Documentation
class AutoGenerationManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(code__istartswith="SUB")
class AutoGeneration(Organization):
objects = AutoGenerationManager()
class Meta:
proxy = True
class UserGenerationManager(models.Manager):
def get_queryset(self):
return super().get_queryset().exclude(code__istartswith="SUB")
class UserGeneration(Organization):
objects = UserGenerationManager()
class Meta:
proxy = True

How i can change my query to work in django?

I want to make a request from two tables at once, I registered dependencies in the class. But the request does not work for me. What is wrong with him?
views.py
def payments(request):
paymentsss = Transaction.objects.select_related("currency_id")[:5]
return render(request, "payments.html", {"paymentsss": paymentsss})
models.py
class Transaction(models.Model):
id = models.BigIntegerField(blank=True, null=False, primary_key=True)
currency_id = models.ForeignKey(Currency, null=True, on_delete=models.CASCADE)
deal_id = models.ForeignKey(Deal, null=True, related_name='deal', on_delete=models.CASCADE)
service_instance_id = models.ForeignKey(ServiceInstance, null=True, related_name='service_instance', on_delete=models.CASCADE)
payment_source_id = models.ForeignKey(PayerPaymentSource, null=True, related_name='payment_source', on_delete=models.CASCADE)
payment_date = models.DateTimeField(blank=True, null=True)
amount = models.IntegerField(blank=True, null=True)
status = models.CharField(max_length=255, blank=True, null=True)
context = models.TextField(blank=True, null=True) # This field type is a guess.
class Meta:
managed = False
db_table = '"processing"."transaction"'`enter code here`
And Currency for example:
class Currency(models.Model):
id = models.SmallIntegerField(blank=True, null=False, primary_key=True)
name = models.CharField(max_length=128, blank=True, null=True)
iso_name = models.CharField(max_length=3, blank=True, null=True)
minor_unit = models.SmallIntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = '"processing"."currency"'
My Error:
I would be glad if there is an example of how to make a larger request. From 3-4 tables.
Change the db_table
class Meta:
managed = False
db_table = 'processing.transaction'
class Meta:
managed = False
db_table = 'processing.currency'
You need to change the column names for the foreign keys: e.g. currency = ForeignKey(...) and deal = ForeignKey(...).
The field is a reference to the object itself, not to the id of the object. You can see that behind the scenes, Django queries using currency_id_id which doesn't make sense.
If your column name is currency_id (in your database), then your field name should be currency.

I wanna create model which Before adding it must be accepted

I would like to create a model which must be accepted by the moderator before adding, after which every change in eg the title in this model must also be accepted
class MangaRequest(models.Model):
title = models.CharField(max_length=191)
type = models.CharField(max_length=30,choices=TYPE, blank=True, default='', null=True)
status= models.CharField(max_length=30, choices=STATUS, blank=True, default='', null=True)
date_start = models.DateField(blank=True, null=True)
data_end = models.DateField(blank=True, null=True)
age_restrictions = models.ForeignKey(OgraniczenieWiekowe, null=True, default='', blank=True)
volumes = models.SmallIntegerField(null=True, blank=True, default=0)
chapter = models.SmallIntegerField(null=True, blank=True, default=0)
is_accept = models.BooleanField(default=False)
delete = models.BooleanField(default=False)
This is my model and I have done it
def save(self, *args, **kwargs):
if self.is_accept == True:
manga = MangaAccept.objects.create(...)
super(MangaRequest, self).delete()
return manga
else:
super(MangaRequest, self).save()
And the same way is about deletes
My question is how can ACCEPT or REJECT for model and everyone field in this model ? Any sugestion ?

Why django inspectdb doesn't create foreign keys correctly on an existing database? [duplicate]

django=2.2.3
mariadb
This error occurs after importing model from an existing database with 'inspectdb' and changed field properties.
class Post(models.Model):
post_id = models.AutoField(primary_key=True)
post_name = models.CharField(max_length=255, blank=True, null=True)
email = models.CharField(max_length=255, blank=True, null=True)
class Rank(models.Model):
rank_id = models.AutoField(primary_key=True)
rank_type = models.IntegerField(blank=True, null=True)
created_at = models.DateTimeField()
# post_id = models.IntegerField(blank=True, null=True)
post_id = models.ForeignKey(Post, on_delete=models.SET_NULL, blank=True, null=True)
Originally, it was # post_id, but I removed "managed = False", changed it to ForeignKey and then "migrate".
As far as I know that if the "post_id" in the "Post" model is "primary_key True", it replaces the "id" value with "post_id". But "Django" keeps calling up the "post_id_id".
There is no command to refer to post_id_id elsewhere.
If you have a solution or something that I'm missing, please give me some advice.
-------Add more after commented by Daniel Roseman --------
class Post(models.Model):
post_id = models.AutoField(primary_key=True)
post_name = models.CharField(max_length=255, blank=True, null=True)
email = models.CharField(max_length=255, blank=True, null=True)
class Gallery(models.Model):
uid = models.AutoField(prymary_key=True)
gallery_name = models.CharField(...)
class Rank(models.Model):
rank_id = models.AutoField(primary_key=True)
rank_type = models.IntegerField(blank=True, null=True)
created_at = models.DateTimeField()
# post_id = models.IntegerField(blank=True, null=True)
post_id = models.ForeignKey(Post, on_delete=models.SET_NULL, blank=True, null=True)
# uid = models.IntegerField(blank=True, null=True)
uid = models.ForeignKey(Gallery, on_delete=models.SET_NULL, blank=True, null=True)
Don't call your ForeignKey post_id. Call it post. The underlying database field is post_id; Django adds the _id suffix automatically.

Django model - how to define foreign key refer to another table?

I'm working with a legay database so I have to set managed = False, which means I cannot update the database schema.
What I'm trying to do is select branches based on project id. Ideally in branches table it should have a project_id as foreign key but the previous system design is another table (branches_projects) stores this relationship.
I have been able to get around some problems using https://docs.djangoproject.com/en/1.11/topics/db/sql/#django.db.models.Manager.raw. raw() would return an RawQuerySet, which is not ideal.
I wonder if there's a way for me to define a foreign key in my branches table, which is the project_id, but refer/link that to the branches_projects table?
class Branches(models.Model):
name = models.CharField(max_length=128)
branchpoint_str = models.CharField(max_length=255)
dev_lead_id = models.IntegerField(blank=True, null=True)
source = models.CharField(max_length=255)
state = models.CharField(max_length=255)
kind = models.CharField(max_length=255)
desc = models.TextField(blank=True, null=True)
approved = models.IntegerField()
for_customer = models.IntegerField()
deactivated_at = models.DateTimeField(blank=True, null=True)
created_at = models.DateTimeField(blank=True, null=True)
updated_at = models.DateTimeField(blank=True, null=True)
codb_id = models.IntegerField(blank=True, null=True)
pm_lead_id = models.IntegerField(blank=True, null=True)
version = models.CharField(max_length=20, blank=True, null=True)
path_id = models.IntegerField(blank=True, null=True)
branchpoint_type = models.CharField(max_length=255, blank=True, null=True)
branchpoint_id = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'branches'
verbose_name_plural = 'Branches'
class Projects(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=40, primary_key=True)
status = models.CharField(max_length=255)
platform = models.CharField(max_length=255)
enabled = models.IntegerField()
path = models.CharField(max_length=128, blank=True, null=True)
tag_prefix = models.CharField(max_length=64, blank=True, null=True)
created_at = models.DateTimeField(blank=True, null=True)
updated_at = models.DateTimeField(blank=True, null=True)
codb_id = models.IntegerField(blank=True, null=True)
template = models.CharField(max_length=64, blank=True, null=True)
image_path = models.CharField(max_length=128, blank=True, null=True)
repository_id = models.IntegerField(blank=True, null=True)
number_scheme = models.CharField(max_length=32)
special_dir = models.CharField(max_length=32, blank=True, null=True)
project_family_id = models.IntegerField()
class Meta:
managed = False
db_table = 'projects'
verbose_name_plural = 'projects'
class BranchesProjects(models.Model):
# project_id = models.IntegerField()
# branch_id = models.IntegerField()
project = models.ForeignKey(Projects, on_delete=models.CASCADE)
branch = models.ForeignKey(Branches, on_delete=models.CASCADE)
class Meta:
managed = False
db_table = 'branches_projects'
My current raw query is like this
SELECT br.id, br.name, br.created_at, br.updated_at,
br.branchpoint_str, br.source
FROM branches as br
LEFT JOIN branches_projects as bp
ON br.id = bp.branch_id
WHERE bp.project_id = %s AND source != 'other'
ORDER BY updated_at DESC
I've finally got it working......
In the model, I use the manytomany as following:
class Branches(models.Model):
name = models.CharField(max_length=128)
project = models.ManyToManyField(Projects,
through='BranchesProjects',
related_name='project')
branchpoint_str = models.CharField(max_length=255)
Then to get the same result as my raw sql, i do the following:
def get_sb(project_id):
result = Branches.objects.filter(
project=Projects.objects.get(id=project_id).id,
).exclude(source='other').order_by('-updated_at')
print result.query
return result