over 7 years ago

Two small issues I run into when dealing with OneToOneField and iterating through a model's fields.

One to One Fields

class A(Model):
    ...
    
class B(Model):
    a = models.OneToOneField(A, primary_key=True)

When models are defined like above, you can grab a reference to B this way:

a_instance = A.objects.get(id=1)
b_instance = a_instance.b

Since B's primary key equals to A's primary key, when Django's ORM creating B in the database, it will not create an 'id' column. Instead, a column named 'A_id' is created. Thus, when ever you want to access B's primary key, you cannot do:

b_instance.id # AttributeError: 'b_instance' object has no attribute 'id'

You have to use b_instance.pk instead.

Model's _meta field

I once had a task which needs to determine if any field within a model instance is empty. To do it, I need a way to loop through all of the fields defined in the instance first:

# _meta allows you to access the fields defined in the model instance

for field in model_instace._meta.fields: 
    ...

Here is the code for determining if a model instance is empty:

def is_model_instance_empty(model_instance):
    # find all of the field's name that are not foreign keys or one to one fields

    # many to many relationship should be added to make it complete

    field_names = [field.name for field in model_instance._meta.fields if (field.get_internal_type() != 'OneToOneField' and field.get_internal_type() !='ForeignKey')]
    counter = 0
    for field_name in field_names:
        if not model_instance.__dict__[field_name]:
            counter += 1
    return counter == len(field_names)
← Understanding Django's Formset 1 React event is null in setState callback →
 
comments powered by Disqus