automatically add a new models to admin page - python

i have a calculator app, inside it i have a Transaction , Family_group , Family_member models see pic below.
i want everytime i try to make a new Transaction there will be a default 1 Family_group and Family_member added automatically, without me starting one each time. is there any way to do it ?
models.py
class Transaction(models.Model):
income_period_choices = (('Weekly', 'Weekly'), ('Fortnightly',
'Fortnightly'))
chp_reference = models.CharField(max_length=50, unique=True)
rent_effective_date = models.DateField(null=True, blank=True)
income_period = models.CharField(max_length=11,
choices=income_period_choices,
null=True,
blank=True, default='Weekly')
property_market_rent = models.DecimalField(help_text='Weekly',
max_digits=7,
decimal_places=2,
null=True,
blank=True)
class FamilyGroup(models.Model):
name_choices = (('FG_1', 'FG_1'), ('FG_2',
'FG_2'), ('FG_3', 'FG_3'), ('FG_4',
'FG_4'), ('FG_5', 'FG_5'))
name = models.CharField(max_length=10, choices=name_choices)
transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE)
family_type = models.ForeignKey(FamilySituation,
on_delete=models.PROTECT,
null=True,
blank=True)
class FamilyMember(models.Model):
transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE)
family_group = models.ForeignKey(FamilyGroup,
on_delete=models.CASCADE,
null=True,
blank=True)
name = models.CharField(max_length=100, null=True, blank=True)
date_of_birth = models.DateField(null=True, blank=True)
relationship = models.ForeignKey(Relationship, on_delete=models.PROTECT)

Without seeing your code, it's hard to help, but this might get you started:
You can override the save method on the Transaction model like so:
class Transaction(models.Model):
...
def save(self, *args, **kwargs):
# add / create family group if it is missing:
if not self.family_group:
self.family_group = <the Family_group instance>
# add / create family member if it is missing:
if not self.family_group.family_member_set.all()
self.family_group.add([<the Family_member instance>])
self.family_group.save()
return super(Transaction, self).save(*args, **kwargs)

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.

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

How can i get in choices=max_guest by room_id when I create django.models?

I have model like this:
class KeyTransfer(Model):
key_out_data = DateTimeField(null=True, blank=True)
key_in_data = DateTimeField(null=True, blank=True)
room_id = ForeignKey(Room, blank=True, null=True, on_delete=CASCADE)
guests = IntegerField(choices=[(x, str(x)) for x in range(Room.objects.get(number=room_id).max_guests)], blank=True, null=True)
notes = CharField(max_length=256, blank=True)
person_id = ForeignKey(Person, null=True, blank=True, on_delete=SET_NULL)
and i understand that i can`t save some value in column "guests" with argument "choices=" as you can see above.
In a consequence I have gotten error:
...django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet. ...
and i see what this error means.
The question is: can I realise some similar condition for "choices" in "guests" do not using django.forms?
It seems that you want to set upper limit for guests field of KeyTransfer model based on its related room model's max_guests field. You can do that by overriding save method and check there if assigned guests is higher than max_guests. See below implementation of this approach:
from django.db import models
from django.core.exceptions import ValidationError
class Person(models.Model):
name = models.CharField(max_length=32)
def __str__(self):
return "<Person {}>".format(self.name)
class Room(models.Model):
max_guests = models.IntegerField()
class KeyTransfer(models.Model):
key_out_data = models.DateTimeField(null=True, blank=True)
key_in_data = models.DateTimeField(null=True, blank=True)
room_id = models.ForeignKey('Room', blank=True, null=True, on_delete=models.CASCADE)
guests = models.IntegerField(blank=True, null=True)
notes = models.CharField(max_length=256, blank=True)
person_id = models.ForeignKey('Person', null=True, blank=True, on_delete=models.SET_NULL)
def save(self, *args, **kwargs):
room = self.room_id
if self.guests > room.max_guests:
raise ValidationError("Assigned guests exceeding related room's maximum limit of {}"\
.format(room.max_guests))
super().save(*args, **kwargs)

django - Runpython function to turn charfield into foreignkey

I've been strugglin to relate a csv imported data model with a spatial data model based on a CharField.
I've created both models and now im trying to transfer the data from one field to a new one to be the ForeignKey field. I made a Runpython funtion to apply on the migration but it goives the an error:
ValueError: Cannot assign "'921-5'":
"D2015ccccccc.rol_fk" must be a "D_Base_Roles" instance.
Here are the models:
class D_Base_Roles(models.Model):
predio = models.CharField(max_length=254)
dest = models.CharField(max_length=254)
dir = models.CharField(max_length=254)
rol = models.CharField(primary_key=True, max_length=254)
vlr_tot = models.FloatField()
ub_x2 = models.FloatField()
ub_y2 = models.FloatField()
instrum = models.CharField(max_length=254)
codzona = models.CharField(max_length=254)
nomzona = models.CharField(max_length=254)
geom = models.MultiPointField(srid=32719)
def __str__(self):
return str(self.rol)
class Meta():
verbose_name_plural = "Roles"
class D2015ccccccc(models.Model):
id = models.CharField(primary_key=True, max_length=80)
nombre_archivo = models.CharField(max_length=180, blank=True, null=True)
derechos = models.CharField(max_length=120, blank=True, null=True)
dir_calle = models.CharField(max_length=120, blank=True, null=True)
dir_numero = models.CharField(max_length=120, blank=True, null=True)
fecha_certificado = models.CharField(max_length=50, blank=True, null=True)
numero_certificado = models.CharField(max_length=50, blank=True, null=True)
numero_solicitud = models.CharField(max_length=50, blank=True, null=True)
rol_sii = models.CharField(max_length=50, blank=True, null=True)
zona_prc = models.CharField(max_length=120, blank=True, null=True)
##NEW EMPTY FOREIGNKEY FIELD
rol_fk = models.ForeignKey(D_Base_Roles, on_delete=models.CASCADE, blank=True, null=True)
def __str__(self):
return str(self.numero_certificado)
class Meta:
managed = True
#db_table = 'domperm2015cip'
verbose_name_plural = "2015 Certificados Informaciones Previas"
ordering = ['numero_certificado']
The Runpython function:
def pop_rol(apps, schema_editor):
roles = apps.get_model('b_dom_edificacion', 'D2015ccccccc')
for r in roles.objects.all():
rol = roles
r.rol_fk = r.rol_sii
r.save()
D_Base_Roles.rol values are all unique, and 921-5 is one of those values.
What am I missing?
You probably need to assign an object, not a string. Change the line
r.rol_fk = r.rol_sii
to
r.rol_fk = D_Base_Roles.objects.get(rol=r.rol_sii)
Maybe adjust to whatever the correct field for looking up D_Base_Roles instances is.
Note: this will make a database query for every iteration of the for-loop

Using one form for two similar models

I have the following models:
class BaseAddress(models.Model):
name = models.CharField(max_length=100)
business_name = models.CharField(max_length=100, blank=True, null=True)
address = models.CharField(max_length=100, blank=True, null=True)
address_2 = models.CharField(max_length=100, blank=True, null=True)
address_3 = models.CharField(max_length=100, blank=True, null=True)
city = models.CharField(max_length=100, blank=True, null=True)
state = models.CharField(max_length=2, blank=True, null=True)
zip_code = models.CharField(max_length=10, blank=True, null=True)
phone = models.CharField(max_length=30, blank=True, null=True)
class Meta:
abstract = True
class ProfileBilling(BaseAddress):
profile = models.OneToOneField(
Profile, related_name='billing_info')
class OrderBilling(BaseAddress):
order = models.OneToOneField(Order, related_name='billing')
name_on_card = models.CharField(max_length=100)
#card_type = models.PositiveSmallIntegerField(
# choices=CARD_TYPE, default=0)
#card_number = models.CharField(
# max_length=16, default=0)
expire_month = models.PositiveSmallIntegerField(
choices=MONTHS, null=True, default=0)
expire_year = models.PositiveSmallIntegerField(
choices=YEARS, null=True, default=1960)
When customers input a billing address, I want to save it in OrderBilling, but I also want to save it in ProfileBilling as their most recent billing address. How do I do so?
How do I go about using forms to save billing address in two different tables when the OrderBilling and ProfileBilling have most of the same fields...?
How do I do this in Django?
Here is my OrderBilling form:
class OrderBillingForm(forms.ModelForm):
class Meta:
model = OrderBilling
exclude = ('order',)
def __init__(self, *args, **kwargs):
super(OrderBillingForm, self).__init__(*args, **kwargs)
self.fields['address'].required = True
self.fields['city'].required = True
self.fields['state'] = USStateField()
self.fields['zip_code'] = us.USZipCodeField()
self.fields['phone'].required = False
self.fields['expire_month'].required = False
self.fields['expire_year'].required = False
def clean(self):
return self.cleaned_data
You can override save() method, But the smarter way in your case would be using post_save signal for this purpose.
After aOrderBilling get saved, You can save its data into ProfileBilling too.
look at some example on google search in case to be familiar with post_save signal,
like:
https://groups.google.com/forum/?fromgroups=#!topic/django-users/2m88qTrqnM8
http://www.djangofoo.com/85/signal-connect-disconnect-django-signals
etc...
then Easyily in your post_save receiver|callback funcstion get the OrderBilling instance
orderbil_instance = kwargs['instance']
And create your ProfileBilling from its data
ProfileBilling.objects.create(name=orderbil_instance.name, ....)
Something like on post_save signal receiver
def do_something(sender, **kwargs):
# Getting OrderBilling instance which get saved just now
orderbil_instance = kwargs['instance']
# Save the data into new ProfileBilling
ProfileBilling.objects.create(name=orderbil_instance.name, ....)

Categories