Daniel W.
Daniel W.

Reputation: 32350

Django related object in save_model

I want a simple created_by field for an entity in Django 3.0:

Snippet from Model:

class Event(models.Model):
    created_by = models.ForeignKey(CustomUser, verbose_name=_('Created by'), on_delete=models.CASCADE, null=False,
                                   blank=False, related_name='created_events', editable=False)

(Migrations applied.)

class EventAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        if obj is not None and obj.created_by is None:
            obj.created_by = request.user
        super().save_model(request, obj, form, change)

On saving from the adminpage I get this error:

RelatedObjectDoesNotExist at /......./Events/event/add/
Event has no created_by.

What am I doing wrong?

What I tried to debug:

def save_model(self, request, obj, form, change):
    print(obj) # Prints the __str__ output of the object correctly!
    if obj is not None and obj.created_by is None:
        user = CustomUser.objects.filter(id=request.user.id).first()
        obj.created_by = user # tried to assign a full model not just from request
    super().save_model(request, obj, form, change)

Upvotes: 0

Views: 372

Answers (1)

user2390182
user2390182

Reputation: 73498

The ... obj.created_by is None ... attribute access does the harm. When you access a non-nullable FK this way it will raise the shown error. You need to test it differently, e.g.

if obj is not None and obj.pk is None:
    # ...

You can also override save_form instead where you have direct access to whether this is a new object:

def save_form(self, request, form, change):
    obj = super().save_form(request, form, change)
    if not change:
        # set user
    return obj

Upvotes: 1

Related Questions