-1

This is a bump post. I have tried various ways and went through all examples here:

and all doesn't seem to work for me.

# models.py in main/ app
from django.contrib.auth.models import User

class Mileage(models.Model):
    owner = models.ForeignKey(User)
    date = models.DateField()
    ... #other parameters

#admin.py
class MileageAdmin(admin.ModelAdmin):
    list_display = ['date', ...]

    def save_model(self, request, instance, form, change):
        user = request.user 
        instance = form.save(commit=False)
        instance.owner= user
        instance.save()
        form.save_m2m()
        return instance

    #views.py
    def home(request):
        form = MileageForm(request.POST or None)    
        context = {"form": form}

        if form.is_valid():
            instance = form.save()

            form = MileageForm()
            context = {"form": form}

        return render(request, 'record_trip.html', context)

I am trying to set the default owner as the logged in user. I tried doing it in ModelAdmin like how other posts do but doesn't seem to work. Can any kind soul point out where am I doing it wrong?

It keeps throwing IntegrityError owner_id cannot be null.

Please pardon me if I made elementary mistakes above. I started coding half a year ago for leisure.

Community
  • 1
  • 1

2 Answers2

1

Not sure if I understood the question correctly. You are trying to set the logged-in user as the default owner of a newly created model?

Currently, you are only setting created_by and modified_by to default to the logged-in user.

#admin.py
class MileageAdmin(admin.ModelAdmin):
    ...

    def save_model(self, request, instance, form, change):
        user = request.user 
        instance = form.save(commit=False)
        if not change or not instance.created_by:
            instance.created_by = user
        instance.modified_by = user
        instance.save()
        form.save_m2m()
        return instance

But those two fields do not even exist in you example model

class Mileage(models.Model):
    owner = models.ForeignKey(User)
    date = models.DateField()
    ... #other parameters

However, you are never actually setting instance.owner to be the request.user. So instance.owner remains to be None, that's why Django complains.

You need to set it before save()ing your instance.

class MileageAdmin(admin.ModelAdmin):
    ...

    def save_model(self, request, instance, form, change):
        instance.owner = request.user

        if not change or not instance.created_by:
            instance.created_by = request.user
        instance.modified_by = request.user
        instance.save()
        form.save_m2m()
        return instance
C14L
  • 12,153
  • 4
  • 39
  • 52
  • Hi thanks for the reply. Yes you are right I copied blindly. I edited my code accordingly to your comment and is shown above. Basically I kept the 'owner' parameters and added in the 'instance.owner=user'. But it still throws the same error. What have I missed? – Koh Jia Rong Jun 05 '16 at 09:26
  • Updated my answer. Remove `instance = form.save(commit=False)` that is overwriting the `instance` you are receiving as a method argument. – C14L Jun 05 '16 at 09:42
  • No luck, it still throws the same error. I wonder if the 'form.save()' in views.py has any influence in this. Could that conflict the instantiation as well? – Koh Jia Rong Jun 05 '16 at 12:24
0

It sounds like the model's save method is getting called somewhere before you've had a chance to set it to the request.user.

You could either find out where that's happening (and perhaps other answers might have a better idea of where that's happening?) or if you wanted a shortcut, you could set the owner attribute to not be a required field, trusting that you'll set it later.

owner = models.ForeignKey(User, blank=True, null=True)

That way, creating the model without the owner wouldn't throw up an integrity error, but you could trust that the owner attribute would eventually be set.

Robert Townley
  • 3,414
  • 3
  • 28
  • 54
  • Thanks for the reply. But for some reason it still throws the same error. I'm beginning to suspect 'form.save()' in views.py has something to do with this. When I trace back the error log it highlights that line. Any advise here? – Koh Jia Rong Jun 05 '16 at 15:13
  • Hmm that's very strange that you'd still be getting the "Cannot be null" error after specifying explicitly that it can be. Shot in the dark: Any chance you didn't run makemigrations and migrate? If not, my apologies: I should have specified that this would also be required. – Robert Townley Jun 05 '16 at 15:15
  • yes it works now. But like you said it sets it as a null by default. I would still require the request.user input because eventually I would wanna publish a table on the site displaying the user's transaction. This is ripping my hair off, I can't seem to identify where I have missed out. – Koh Jia Rong Jun 05 '16 at 16:18