开发者

make the user in a model default to the current user [duplicate]

This question already has answers here: How to assign currently logged in user as default value for a model field? (5 answers) Closed 6 years ago.

I have the following:

from django.contrib.auth.m开发者_如何学JAVAodels import User

class ClientDetails(models.Model):
    created_by = models.ForeignKey(User)
    ...

How do I make created_by default to the currently logged in user?

(I want to do this so I can hide it in the admin view mainly but also because when I save an instance I don't want to be filling it every time)


Since you need to get the currently logged in user from a request object you cannot get it in the model's save-method,but you can eg override the model admin's save_model-method:

class MyAdmin(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


You have to override get_changeform_initial_data method in your model Admin class in admin.py as follows:

# admin.py

class ClientDetailsAdmin(admin.ModelAdmin):
    def get_changeform_initial_data(self, request):
        get_data = super(ClientDetailsAdmin, self).get_changeform_initial_data(request)
        get_data['created_by'] = request.user.pk
        return get_data

admin.site.register(ClientDetails, ClientDetailsAdmin)

In such way you obtain the most elegant solution since the created_by field is filed up when you create new record.


I had a similar issue recently, this is from my views.py file

def CircleAdd(request):

    form = CircleAddForm(request.POST)

    if form.is_valid():

        Circle = form.save(commit=False)
        Circle.Author = request.user
        Circle = Circle.save()

And then I had a form for the 'circles' model, which was just a wrapper really (forms.py)

class CircleAddForm(ModelForm):
    class Meta:
        model = Circle

Remember to import the form in your view!

Edit: not even sure if you even need to bother with the separate form, the key bit is the fake commit, followed by the real


Building on the accepted answer, if you're looking to do this with Class Based views, you can follow the instructions in the docs, overriding the form_valid() method on the class view:

# views.py

from django.views.generic.edit import CreateView

class CreateClient(CreateView):
    def form_valid(self, form):
        form.instance.created_by = self.request.user
        return super(CreateClient, self).form_valid(form)


Normal modelfields have a default argument. But ForeignKeys do not as far as I know, so I guess you need to work with a post_save signal.


I found:

from django.db import models
from django.contrib.auth.models import User

class CurrentUserField(models.ForeignKey):
    def __init__(self, **kwargs):
        super(CurrentUserField, self).__init__(User, null=True, **kwargs)

    def contribute_to_class(self, cls, name):
        super(CurrentUserField, self).contribute_to_class(cls, name)
        registry = registration.FieldRegistry()
        registry.add_field(cls, self)

class ClientDetails(models.Model):
    created_by = CurrentUserField()
...

from here. But isn't there an easier way?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜