models.py
i have create foreignkey in table paymentsDetails i have stripe payment method which is working when user login session is created and by using session value i get the primarykey of that user by using 'ORM' method and then assign this primary key of specific user into the paymentdetails models field named as user_account_id
but i am getting error that i cannot assign 1 to PaymentsDetail.User_account_id must be a instance of UserAccountModel
class UserAccountModel(models.Model):
ContactEmail = models.EmailField(max_length=30)
FirstName = models.CharField(max_length=30)
LastName = models.CharField(max_length=40)
Counrty = models.CharField(max_length=50)
Phone = models.IntegerField()
ChooseUserName = models.CharField(max_length=30)
password = models.CharField(max_length=32)
EnterCaptcha = models.CharField(max_length=4)
payments = models.BooleanField(max_length=6, default=False)
showsponsor = models.CharField(max_length=30, default=False)
RegisteredDate = models.DateTimeField(auto_now_add=True, blank=True)
ActivationOn = models.DateField(auto_now_add=False,blank=True)
expiry_date = models.DateField(auto_now_add=False,blank=True)
def __str__(self):
return self.FirstName + ":" + self.ChooseUserName
class PaymentsDetail(models.Model):
refrer_name = models.CharField(max_length=32,default="", editable=False)
sponser_name = models.CharField(max_length=32)
status = models.CharField(default='comped', max_length=32)
s_id = models.CharField(max_length=32)
registered = models.DateTimeField(auto_now_add=True)
activated_date = models.DateField(auto_now_add=False)
Due_Date = models.DateField(auto_now_add=False)
payment = models.CharField(default='$',max_length=32)
User_Account_id = models.ForeignKey(UserAccountModel, on_delete=models.CASCADE, default=True, editable=True)
addprogrameReference = models.ForeignKey(AddProgramModel, on_delete=models.CASCADE, default=True, editable=True)
class Meta:
ordering = ['User_Account_id', 'addprogrameReference']
def str(self):
return self.refrer_name + ":" + self.user_account
i am getting the error
cannot assign 1 to PaymentsDetail.User_account_id must be a instance
of UserAccountModel
views.py
print("user payment"+str(charge.amount))
pays = str(charge.amount)
user_id = random.randint(0, 999) # returns a random integer
user = User.objects.get(username=str(rerredby))
userKey = user.pk
print("this one is for user upper")
# saving record
payment_insertion = PaymentsDetail.objects.create(
User_Account_id=userKey,
refrer_name=rerredby,
sponser_name=rerredby,
s_id=str(user_id),
registered=datetime.now(),
activated_date=datetime.now(),
Due_Date=datetime.now(),
payment=str(pays + "$"),
)
payment_insertion.save()
Simply change this string:
payment_insertion = PaymentsDetail.objects.create(
User_Account_id=user,
...)
You are trying to assign int object where Django expects an instance.
Your view implementation is not right. The model class expects the field User_Account_id to be an instance of of UserAccountModel (since, your model definition User_Account_id = models.ForeignKey(UserAccountModel, on_delete=models.CASCADE, default=True, editable=True) told it to expect it regardless of the your field name ending with an id). therefore, retrieve the UserAccountModel instance from db first.
However, if you still want to pass the id to instead of an object change the following in your view.
User_Account_id_id=userKey
ForeingKey fields can be populated by id instead of the concerned model object. But you have to append _id at the end of the field name e.g.
#models.py
class Author(models.Model):
name = models.CharField(max_length=250)
class Book(models.Model):
name = models.CharField(max_length=250)
author = models.ForeignKeyField(Author, on_delete=models.CASCADE)
# views.py
def create_book(request):
name = request.POST.get('name', '')
author_id = request.POST.get('author_id', '')
Book.objects.create(name=name, author_id=author_id)
return HttpResponse(status=201)
Notice that there is no author_id field defined in the Book model. This field is implicitly defined by django ORM once you defined author field as a ForeignKey reference to Author model.
Related
Note: IF INFORMATION BELOW IS NOT CLEAR TO UNDERSTAND - PLEASE ASK ME, I WILL UPDATE AND POST INFORMATION YOU NEED | It is important for me
In Warehouse(models.Model) I have amount attribute and
in ChosenProduct(models.Model) - quantity
I'm trying to get amount in Warehouse through chosen_products instance in App_formSerializer to add the quantity of chosen_product
But I can not get the chosen_products objects from instance
--> below Out:
class WarehouseSerializer(serializers.ModelSerializer):
category_name = serializers.ReadOnlyField(
source='category_product.category_name')
posted_user = serializers.ReadOnlyField(
source='posted_user.username')
class Meta:
model = Warehouse
fields = ['id', 'category_product', 'category_name', 'condition',
'product_name', 'amount', 'barcode', 'f_price', 'created_at', 'updated_at', 'posted_user']
class ChosenProductSerializer(serializers.ModelSerializer):
product_info = WarehouseSerializer(source='product', read_only=True)
period_info = Product_periodSerializer(source='period', read_only=True)
class Meta:
model = ChosenProduct
exclude = ('app_form',)
class App_formSerializer(serializers.ModelSerializer):
chosen_products = ChosenProductSerializer(many=True)
def update(self, instance, validated_data):
instance.terminated = validated_data.get('terminated', instance.terminated)
if instance.terminated == True :
print('-----------TRUE--------------------')
print(instance.chosen_products)
print('-----------PRINT--------------------')
instance.save()
return instance
class Meta:
model = App_form
fields = '__all__'
Out
-----------TRUE--------------------
creditapi.ChosenProduct.None
-----------PRINT--------------------
QUESTION UPDATED
models.py
class Warehouse(models.Model):
category_product = models.ForeignKey(
Category_product, on_delete=models.CASCADE)
product_name = models.CharField(max_length=200, unique=True)
condition = models.BooleanField(default=False)
amount = models.IntegerField()
barcode = models.BigIntegerField()
f_price = models.CharField(max_length=255, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
posted_user = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
def __str__(self):
return self.product_name
class App_form(models.Model):
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,12}$', message="Phone number must be entered in the format: '998981234567'. Up to 12 digits allowed.")
terminated = models.BooleanField(default=False)
name = models.CharField(max_length=150)
phone_number = models.CharField(validators=[phone_regex], max_length=13)
def __str__(self):
return self.surname
class ChosenProduct(models.Model):
product = models.ForeignKey(Warehouse, on_delete=models.CASCADE)
quantity = models.IntegerField()
app_form = models.ForeignKey(App_form, on_delete=models.CASCADE, related_name='chosen_products')
def __str__(self):
return self.product.product_name
If you write instance.chose_products you access the manager, not the QuerySet that contains the items. You can use .all() to obtain the QuerySet with all the objects:
print(instance.chosen_products.all())
If you access a ForeignKey in reverse, you have a manager, since zero, one, or more elements can refer to the instance.
You can for example aggregate over the chose_products, for example if you want to retrieve the number of related chose_products, you can use:
print(instance.chosen_products.count())
I would however advise not store (aggregated) data in the App_form, but aggregate data when you need it. Data duplication is an anti-pattern, and it turns out it is hard to keep data in sync.
i have a table in models.py with class name registration and another table profileimage with foreignkey relation with registration model now i want to
get verify the email address by using profileimage table
models.py
class Registration(models.Model):
YourName = models.CharField(max_length=30)
Email = models.EmailField(max_length=254,verbose_name='email')
password = models.CharField(max_length=254,verbose_name='password',null=True)
PhoneNumber = models.IntegerField(null=True,verbose_name='email')
CompanyName = models.CharField(max_length=30)
WebSiteName = models.CharField(max_length=30)
NumberOfEmplyes = models.IntegerField(null=True)
YourRoleInCompany = models.CharField(max_length=100)
SoftwareUsedBefore = models.CharField(max_length=30)
Turnout2017 = models.IntegerField(null=True)
Turnover2016 = models.IntegerField(null=True)
Description = models.CharField(max_length=30)
ClientArgument = models.CharField(max_length=2000,null=True)
PaymentsPlan = models.CharField(max_length=100,null=True)
class ProfileImages(models.Model):
MemeberName = models.OneToOneField('Registration',on_delete=models.CASCADE,blank=True)
profile_image = models.ImageField(upload_to='media/profile_image',default=True,null=True)
def __str__(self):
return "user profile image"
now for example i have email adress which i get from sessions now e.g example#stack.com now i want to use this email to fillter record in this way.
profile_image=
ProfileImages.objects.filter(Registration__Email=email).select_related()
let me know what is the exact way to perform this query
ProfileImages.objects.get(MemeberName__email=email)
I think I would do it as follows
class ProfileImages(models.Model):
profile_image = models.ImageField(upload_to='profile_image',blank=True,null=True)
...
And in the Registration
class Registration(models.Model):
YourName = models.CharField(max_length=30)
Email = models.EmailField(max_length=254,verbose_name='email')
....
image_profile = models.ForeignKey(
ProfileImages, verbose_name='Profile Image', on_delete=models.CASCADE, blank=True, null=True)
Notice, that 'media' word in upload_to it is better to define it in settings.py
I've been reading similar questions to mine but they didn't help me.
I'm getting this error while I try to submit my form:
Cannot assign "9": "Characterweapons.weaponid" must be a "Weapons" instance.
This "9" is the ID from the weapon I got from my form, so that's very good, but when I try to put it in my weaponid column in my table Characterweapons, it gives me the error.
models.py:
from __future__ import unicode_literals
from django.db import models
class Category(models.Model):
categoryid = models.AutoField(db_column='CategoryID', primary_key=True) # Field name made lowercase.
categoryname = models.CharField(db_column='CategoryName', max_length=50, blank=True, null=True) # Field name made lowercase.
class Meta:
managed = True
db_table = 'category'
def __str__(self):
return self.categoryname
class Characters(models.Model):
characterid = models.AutoField(db_column='CharacterID', primary_key=True) # Field name made lowercase.
name = models.CharField(db_column='Name', unique=True, max_length=255) # Field name made lowercase.
level = models.IntegerField(db_column='Level') # Field name made lowercase.
credits = models.IntegerField(db_column='Credits') # Field name made lowercase.
class Meta:
managed = True
db_table = 'characters'
def __str__(self):
return '%s %s %s' % (self.name, self.level, self.credits)
class Weapons(models.Model):
weaponid = models.AutoField(db_column='WeaponID', primary_key=True) # Field name made lowercase.
weaponname = models.CharField(db_column='WeaponName', unique=True, max_length=255) # Field name made lowercase.
class Meta:
managed = True
db_table = 'weapons'
def __str__(self):
return '%s %r' % (self.weaponname, self.weaponid)
class Characterweapons(models.Model):
characterid = models.ForeignKey(Characters, models.DO_NOTHING, db_column='CharacterID') # Field name made lowercase.
weaponid = models.ForeignKey(Weapons, models.DO_NOTHING, db_column='WeaponID', blank=True, null=True) # Field name made lowercase.
categoryid = models.ForeignKey(Category, models.DO_NOTHING, db_column='CategoryID', blank=True, null=True) # Field name made lowercase.
quantity = models.IntegerField(db_column='Quantity', blank=True, null=True) # Field name made lowercase.
class Meta:
managed = True
db_table = 'characterweapons'
def __str__(self):
return '%s' % (self.quantity)
class DjangoMigrations(models.Model):
app = models.CharField(max_length=255)
name = models.CharField(max_length=255)
applied = models.DateTimeField()
class Meta:
managed = True
db_table = 'django_migrations'
I don't know if it is a FK problem, PK... no idea and I cannot find information to solve it...
views.py: (where the error has to be):
def submission(request):
print("Registered successfully")
Name = request.POST["Name"]
Level = request.POST["Level"]
Credits = request.POST["Credits"]
Mainhand = request.POST["Mainhand"]
Offhand = request.POST["Offhand"]
info = Characters(name=Name,level=Level,credits=Credits)
info.save()
mh=
infomh = Weapons.objects.values_list('weaponid',flat=True)
a=0;
for a in infomh:
if a == Mainhand:
a = Mainhand;
print("a: ")
print(a)
print("Mainhand")
print(Mainhand)
print("infmh:")
print(infomh)
charid = Characters.objects.latest('characterid')
info_mh = Characterweapons(characterid=charid,categoryid=1,weaponid=a)
info_mh.save()
#info_oh = Characterweapons(characterid=charid,weaponid=9,categoryid=2)
#info_oh.save()
return return_charnames(request)
With these prints I made sure that the values of my weaponsID are correct, they are.
I also wanna point out that the value=9 in the column "weaponid" exists in "Weapons" table.
Thanks all.
I think you better first fix your models. In Django a ForeignKey is conceptually a reference to an object to which you refer, not the id. Of course in the database it is stored as an id, but that is a layer that you should not care much about.
So I would advice to first rename the fields like weaponid to weapon:
class Characterweapons(models.Model):
character = models.ForeignKey(Characters, models.DO_NOTHING, db_column='CharacterID')
weapon = models.ForeignKey(Weapons, models.DO_NOTHING, db_column='WeaponID', blank=True, null=True)
category = models.ForeignKey(Category, models.DO_NOTHING, db_column='CategoryID', blank=True, null=True)
quantity = models.IntegerField(db_column='Quantity', blank=True, null=True)
# ...
Now if you construct a ForeignKey with the name fieldname, Django actually introduces two fields: the fieldname which is - like said before - a reference to a model object to which the ForeignKey refers, and a field fieldname_id that stores the id (the primary key) of that object. These two fields thus act like "twins".
We can then rewrite the submission view like:
def submission(request):
print("Registered successfully")
name = request.POST["Name"]
level = request.POST["Level"]
credits = request.POST["Credits"]
mainhand = request.POST["Mainhand"]
offhand = request.POST["Offhand"]
info = Characters.objects.create(name=name, level=level,credits=credits)
if Weapons.objects.filter(weapon_id=mainhand).exists():
a = mainhand
info_mh = Characterweapons.objects.create(
character_id=info.pk,
category_id=1,
weapon_id=a
)
return return_charnames(request)
In the above I did some refactorings as well:
In Python variables in functions typically have lowercase names;
you do not need to loop over weapon_ids, you can use an EXISTS query, which is typically faster;
Instead of first constructing a model instance, and then obj.save() it, you can use Model.objects.create(..) instead;
you probably do not want to fetch the latest(..) value, but use the pk of the info object instead, since that is the one we constructed, and furthermore if there is no order defined (like here), the order can be any order the database likes, not per se the latest one added.
You probably still need to rewrite hardcoded identifiers (like a=1, and category_id=1, since it is perfectly possible that those objects do not exist in the database).
Your foreignkey weaponid in the model Characterweapons is a Weapon instance not only its id.
From that id, query the object and assign it.
I create tests for api and models. The issue is to test if models are created.
User model is this one:
class User(AbstractUser):
CUSTOMER = 1
EXECUTER = 2
USER_TYPES = (
(CUSTOMER, 'Customer'),
(EXECUTER, 'Executer'),
)
user_type = models.IntegerField(choices=USER_TYPES, default=EXECUTER, verbose_name='Тип пользователя')
balance = models.DecimalField(decimal_places=2, max_digits=7, default=0, verbose_name='Баланс')
def __str__(self):
return self.username
Task models look like:
class Task(models.Model):
title = models.CharField(max_length=255, verbose_name='Заголовок')
description = models.CharField(max_length=255, verbose_name='Описание')
money = models.DecimalField(max_digits=7, decimal_places=2, default=0, verbose_name='Цена')
assignee = models.ForeignKey('users.User', related_name='assignee', null=True, verbose_name='Исполнитель')
created_by = models.ForeignKey('users.User', related_name='created_by', verbose_name='Кем был создан')
I want to test models creation, but test model doesn't want to be made. Problem is in assignee and created by fields.
This is my test:
def test_creating_models_instance(self):
User.objects.create(username="assignee", first_name="First_name_2", last_name="Surname_2",
user_type=2, balance="16155.00")
User.objects.create(username="created_by", first_name="First_name_1", last_name="Surname_1",
user_type=1, balance="16155.00")
Task.objects.create(title="Task_1", description="Description_1", money="155.00",
assignee="assignee", created_by="created_by")
And I have mistake like:
self.field.remote_field.model._meta.object_name,
ValueError: Cannot assign "'assignee'": "Task.assignee" must be a "User" instance.
You need use instance instead of string:
def test_creating_models_instance(self):
assignee = User.objects.create(
username="assignee", first_name="First_name_2",
last_name="Surname_2", user_type=2, balance="16155.00")
created_by = User.objects.create(
username="created_by", first_name="First_name_1",
last_name="Surname_1", user_type=1, balance="16155.00")
Task.objects.create(title="Task_1", description="Description_1", money="155.00",
assignee=assignee, created_by=created_by)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I have an abstract model class userabstract which has fields id(primary key), name(char field) and email(email field).
I am inheriting this class in two classes user, usertemp. After signing up, i want the data to be stored in usertemp. When user clicks on confirmation mail then that data will be transferred to user class.
But whats happening is, whenever someone signs up, usertemp model is updated instead of creating a new one. Same thing is happening with user class
Here is the code for models and views
class UserAbstract(models.Model):
id = models.AutoField(db_column='ID', primary_key=True, default=1) # Field name made lowercase.
name = models.CharField(db_column='NAME', max_length=100, default='') # Field name made lowercase.
email = models.CharField(db_column='EMAIL', max_length=100, default='') # Field name made lowercase.
def __str__(self):
return self.name
class Meta:
abstract = True
#python_2_unicode_compatible
class User(UserAbstract):
def __str__(self):
return self.name ;
class Meta:
managed = True
db_table = 'User'
#python_2_unicode_compatible
class Validation(models.Model):
key = models.AutoField(primary_key=True)
key_data = models.CharField(max_length=100, default='')
create_time = models.DateTimeField()
expire_time = models.DateTimeField()
def __str__(self):
return self.key_data
#python_2_unicode_compatible
class UserTemp(UserAbstract):
validation_key = models.ForeignKey(Validation, models.DO_NOTHING, related_name='+', default='') # Field name made lowercase.
verified = models.BooleanField(default=False)
def __str__(self):
return self.validation_key.key_data
views.py
def signup(request):
if request.method == 'POST':
form = FormTemp(request.POST, request.FILES)
if form.is_valid():
primary = form.cleaned_data['email']
try:
qdict = {}
qdict['email'] = primary
user = UserTemp.objects.get(**qdict)
if user.verified==True:
return HttpResponse("Account already exists")
except:
pass
email = form.cleaned_data['email']
signer = hashlib.sha256()
signer.update(primary)
validation_key = signer.hexdigest()
confirm_key = request.build_absolute_uri('/signup-confirm/')+'?key='+validation_key
send_mail('Confirm Your Mail', confirm_key, settings.EMAIL_HOST_USER, [email,])
valid = Validation(key_data=validation_key, create_time=datetime.now(), expire_time=datetime.now()+timedelta(days=30))
valid.save()
argsdict = {}
argsdict['name'] = form.cleaned_data['name']
argsdict['email'] = form.cleaned_data['email']
argsdict['validation_key'] = valid
argsdict['verified'] = False
usertemp = UserTemp(**argsdict)
usertemp.save()
return HttpResponse("Confirmation mail sent")
else:
return HttpResponse('Invalid Data')
else:
return HttpResponse('What are you doing here ? Tresspass')
The valid.save() is working fine and every time validation key is being saved but the usertemp contains only one model and that is the most recent one.
When i tried force_insert=True then its telling me that duplicate entry exist with same primary key. As you can see, the primary key field id is AutoField then why django not creating a new model when i am writing usertemp = UserTemp(**argsdict)
The problem here is that you've given your AutoField a default value. You're telling Django to assign that field the value 1 if you don't provide it, which means that you keep writing rows with the same id.
So just get rid of that default.
The broader point to understand is that defaults are a Django-level feature, while AutoField is a database-level feature. From the perspective of the database, there's no difference between explicitly assigned column values and Django default column values.