Cannot assign "40": "Group.groupParent_id" must be a "Group" instance - python

I want to add group from my group model. this one is recursive on parent-children relation.
But when I want to create a group with a children. I have the error
my model:
class Group(models.Model):
group_id = models.AutoField(primary_key=True)
groupParent_id = models.ForeignKey('self', blank=True, null=True, related_name='children', on_delete=models.CASCADE)
group_name = models.CharField(max_length=100, null=False, blank=False, unique=True)
views.py:
My function which provoke error on line 18 GroupParent_id :
def add_group_fromcoa(request): # add type and subtype of chart of account as first serie of group and subgroup
# ------ Type adding -----
types = ChartOfAccount.objects.order_by().values_list("field_type", flat=True).distinct()
for type_types in types:
upload_data = Group.objects.get_or_create(group_name=type_types,)
types = ChartOfAccount.objects.order_by().values_list('field_subtype', flat=True).distinct()
for type_types in types:
looktype = ChartOfAccount.objects.filter(field_subtype=type_types).values('field_type').first()
print("retour Groupe: {}".format(looktype['field_type']))
looktyp= Group.objects.filter(group_name=looktype['field_type']).values('group_id').first()
print("IDGroup: {}".format(int(looktyp['group_id'])))
upload_data = Group.objects.get_or_create(
group_name=type_types,
groupParent_id=int(looktyp['group_id']))
return redirect(home)

When you create a foreign key relation in Django, Djano's default behavior is to name the column name <object_column_name>_id. So, when you add the field groupParent_id, Django names the database field groupParent_id_id. Now, when you have a foreign key on a Django model, you have two ways of referencing that relationship: you can use an object, or you can use a database primary key. If you use the name of the field from the model, the reference has to be an object. However, if you add _id onto the end, you can use the primary key, as you're trying to do here. If you change groupParent_id=int(looktyp['group_id']) to groupParent_id_id=int(looktyp['group_id']), this should work.

Related

How to filter objects based on model fields in Django

I have a Model named Order that has a foreign key pointed to the current user
class Order(models.Model):
customer_name = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='customer_name',
)
order_individual_price = models.IntegerField(default=1)
order_default_price = models.IntegerField(default=1)
order_name = models.CharField(max_length=200)
order_quantity = models.IntegerField(default=1)
order_total_price = models.IntegerField(default=1)
I currently have 2 order objects from 2 different users. How would I filter the objects so that it only shows the one from a specific user?
I currently have the following code: Order.objects.filter(customer_name='chironsus')
It gives me this error: ValueError: Field 'id' expected a number but got 'chironsus'.
'chironsus' is not the primary key of a User, it is perhaps the username. You can filter that with:
Order.objects.filter(customer_name__username='chironsus')
Note: A ForeignKey does not store the string representation (or name) of the
referenced object in the column, it stores the primary key of the record it
references in a column with an _id suffix to a ForeignKey field. Therefore
ForeignKeys usually do not end with a _name suffix. You might want to
consider renaming the customer_name field to customer.

Allow individual model fields in Django to be null but prevent all of them from being null

i have a Django model class as follows:
class IPGroup(BaseModel):
"""
Stores IP Groups
"""
name = models.CharField(max_length=50, unique=True)
team = models.ForeignKey(Team, on_delete=models.CASCADE)
_ips = models.ManyToManyField(IP, through='connectivity_service.IPGroupToIP', null=True)
_cidrs = models.ManyToManyField(CIDR, through='connectivity_service.IPGroupToCIDR', null=True)
_ip_groups = models.ManyToManyField('self', through='connectivity_service.IPGroupToIPGroup', null=True,
symmetrical=False)
def __unicode__(self):
return f'{self.name}'
class Meta:
app_label = 'connectivity_service'
As is evident, the fields _ips,_cidrs and ip_groups can be null in the database.However, I want to prevent all 3 of them being null together when the model is saved. In other words, when the model is saved, atleast one of those 3 fields should not be null.
Firstly, null doesn't have any meaning with a many-to-many field, as that's not actually a column in the database but an entry in a completely separate table.
In any case, if you want to require that at least one of those fields is non-empty, you need to do it at validation time; it's not something you can just specify in the model definition.
But note also, for the same reason as above, you can't do this before creating the model initially; many-to-many fields can't have a value before creation, because they need the ID to create the item in the through table.

Django query selecting values and objects

I have a problem with the queries when selecting values and objects. Here is a sample structure:
class Property(models.Model):
name = models.CharField(max_length=70, blank=True, verbose_name="Property Name")
type = models.CharField(max_length=10)
class Agreement(models.Model):
property = models.ForeignKey(Property, on_delete=models.CASCADE, related_name="prop")
renter = models.ForeignKey(User, verbose_name="Kiracı", related_name = "renter01")
Here is the first filter.
qs1 = Agreement.objects.all()
This one returns property and renter as objects. So I can refer the object details such as
for q in qs:
print(q.renter.firstname)
Here is the second filter.
When I need only some fields I use this filter:
qs2 = Agreement.objects.all().values('renter',...)
In that case the query returns the pk value of the renter user; and I cannot use it as object.
Is there a way that I can select certain columns and keep the objects in it as objects?
If you want renters, you should query User, not Agreement.
renters = User.objects.exclude(renter01=None)
(Note, having renter01 as the reverse relation makes no sense; unless you have a good reason, you should keep it as the default, which is agreement_set.)

Django relation lookup not creating expected query

I'm using Django 1.11.6, python 3.4.2, postgresql, PyCharm 4.5.2, and windows 10 (only for development purposes).
The goal is to utilize the 'Lookups that span relationships' from the Django docs.
# models
class AlphaType(models.Model):
page_type = models.CharField(max_length=50, primary_key=True, null=False)
created_on = models.DateTimeField(auto_now_add=True)
modified_on = models.DateTimeField(auto_now=True)
class AlphaBoard(models.Model):
title = models.CharField(max_length=50)
alpha_text = models.TextField(max_length=30000)
created_on = models.DateTimeField(auto_now_add=True)
modified_on = models.DateTimeField(auto_now=True)
fk_page_type = models.ForeignKey(AlphaType, on_delete=models.CASCADE, default='general')
#views
....
q = AlphaBoard.objects.filter(fk_page_type__page_type='general')
print(q.query)
....
Just fyi, the tables have the app name prepended to the model name and the foreign key has 'id' appended to the foreign key column name.
Result of the query print.
SELECT
"alpha_alphaboard"."id", "alpha_alphaboard"."title",
"alpha_alphaboard"."alpha_text", "alpha_alphaboard"."created_on",
"alpha_alphaboard"."modified_on", "alpha_alphaboard"."fk_page_type_id"
FROM
"alpha_alphaboard"
WHERE
"alpha_alphaboard"."fk_page_type_id" = "general"
What I was expecting.
SELECT
"alpha_alphaboard"."id", "alpha_alphaboard"."title",
"alpha_alphaboard"."alpha_text", "alpha_alphaboard"."created_on",
"alpha_alphaboard"."modified_on", "alpha_alphaboard"."fk_page_type_id"
FROM
"alpha_alphaboard"
INNER JOIN "alpha_alphaboard" ON "alpha_alphatype"
"alpha_alphaboard"."fk_page_type_id" = "alpha_alphatype"."page_type"
WHERE
"alpha_alphatype"."page_type" = "general"
Questions
Why is the query ignoring the page_type relation from the filter? Look at the result of the printed query and the filter within the views. I should also add that I had a related_name="fk_page_type" within the AlphaBoard.fk_page_type, but I removed it. So a follow up question is why is it still picking up the related_name?
How do you use the "relationship" from the docs to get the expected?
Is there a way to specify the join type?
Since page_type is the primary key of the AlphaType model and its value is just written in the fk_page_type column of the AlphaBoard table, no join is needed:
q = AlphaBoard.objects.filter(fk_page_type__page_type='general')
is the same as
q = AlphaBoard.objects.filter(fk_page_type_id='general')
the field of the related model you are using in your filter is the exact foreign key value that is written in the primary table.
As for the related_name, it is used to access the reverse relation:
class AlphaBoard(models.Model):
fk_page_type = models.ForeignKey(AlphaType, on_delete=models.CASCADE, related_name='boards')
t = AlphaType(...)
boards = t.boards.all() # gives all boards with type t
boards = t.alphaboard_set.all() # default: lowermodelname_set

How to filter a property in Django

I am currently having trouble with filtering data.
Model
class Member(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
team_id = models.UUIDField(null=True)
username = models.CharField('', max_length=30)
is_active = models.BooleanField(default=False)
#property
def organization_id(self):
"""This is to get the organization Id
"""
team = Team.objects.get(pk=self.team_id)
return team.organization_id
and now I am planning to filter all the members with the organation_id = 1.
This is what I need:
memberList = Member.objects.filter(organization_id='1')
So I got this error:
Cannot resolve keyword 'organization_id' into field. Choices are: id, is_active, team_id, username
How can I filter the members using organization_id?
You don't have any field named organization_id in you model Member, that's why the error.
Intead you might want this :
result_list = []
memberList = Member.objects.all()
for item in memberList :
if item.organization_id() == '1' :
result_list.append(item)
print result_list
The resultant list result_list will contain all the required objects of model Member.
Thanks.
According to what I understood from your questions, I assumeed that you have Two Model class.
Lets make example
class Organization(models.Model):
name = models.CharField(max_length=30)
class Member(models.Model):
username = models.CharField(blank=True, max_length=30)
team = models.ForeignKey(Organization)
You use UUIDField as Primary Key. I omitted it. Django make primary key field automatically. I am curious what was your purpose to use UUID Field in the first place.
Anyway, if you create Organization first time. PK number will be 1.
Lets say you are testing in python shell
python manage.py shell
>> import your models
>> Organization.objects.create(name="test1")
then you can connect this Organization with Foreign Key relationship.
>> organization = Organization.objects.get(name="test1")
>> Member.objects.create(username="bob", team=organization)
Next time if you want to get members who in test1 organization.
>> organization = Organization.objects.get(name="test1")
>> Member.objects.filter(team=organization)
or just put PK number of organization 'test1'. Let's say it's 1
>> Member.objects.filter(team=1)
If fixed that you only want to get members who have organization '1', you can add custom manager in model.
class OrganizationManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(team=1)
class Organization(models.Model):
name = models.CharField(max_length=30)
class Member(models.Model):
username = models.CharField(blank=True, max_length=30)
team = models.ForeignKey(Organization)
objects = models.Manager()
organization = OrganizationManager()
you can get members like below
>> Member.organization.all()
it will return members who are in organization pk 1.
memberList = Member.objects.all().annotate(org_id=F('calculate organization id over other model fields')).filter(org_id='1')
in my case this helps, there F is
from django.db.models import F

Categories

Resources