Yeah, you may have noticed that I've been working on the blog lately. Poor openclue.org got flooded with already posted RSS feeds again. This happens all to often. Sorry guys.
Anyway, this blog system has the ability to have more than one person post articles. In the past, sjohannes used to post here too. The model for articles looks something like this:
1 2 3 4 5 6 7 8 9 10 11 | from django.contrib.auth.models import User from django.db import models import datetime class Article(models.Model): title = models.CharField(max_length=250) slug = models.SlugField() article = models.TextField() pub_date = models.DateTimeField( default=datetime.datetime.now) publisher = models.ForeignKey(User) |
As you can see, there's a ForeignKey to django.contrib.auth.models.User. The question here is: how do I make the "publisher" field default to the currently logged in user? It was harder than I thought it should be, but it can be done using hooks in the ModelAdmin for the Article model. Take a look:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class ArticleAdmin(admin.ModelAdmin): list_display = ('pub_date', 'publisher', 'title', 'slug') search_fields = ('title', 'article') prepopulated_fields = { 'slug': ('title',), } def get_form(self, req, obj=None, **kwargs): # save the currently logged in user for later self.current_user = req.user return super(ArticleAdmin, self).get_form(req, obj, **kwargs) def formfield_for_dbfield(self, field, **kwargs): from django import forms from django.contrib.auth import models if field.name == 'publisher': queryset = models.User.objects.all() return forms.ModelChoiceField( queryset=queryset, initial=self.current_user.id) return super(ArticleAdmin, self).formfield_for_dbfield(field, **kwargs) admin.site.register(models.Article, ArticleAdmin) |
As you can see, I overload "get_form" for one purpose: It takes the HttpRequest as the first argument, which we can use to save the currently logged in user. The other method that's overloaded, "formfield_for_dbfield" is called for every field in the model, and is made for the purpose of specifying your own custom form fields (and widgets). In this case, we use the same field type that the admin would have used - "ModelChoiceField" and give it an initial, which is the id of the currently logged in user.
There you have it. It's a little hacky, but it's the only way I could find to do it. If you've seen a cleaner way, let me know!"

Hi there,
I'm right now dealing with the same issue, sort of; except I don't want to leave the choice to the currently logged-in user.
I've found this in the Django doc, thought you might be interested:
---
ModelAdmin.save_model(self, request, obj, form, change)ΒΆ
The save_model method is given the HttpRequest, a model instance, a ModelForm instance and a boolean value based on whether it is adding or changing the object. Here you can do any pre- or post-save operations.
For example to attach request.user to the object prior to saving:
class ArticleAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.user = request.user
obj.save()
---
( source: http://docs.djangoproject.com/en/1.0/ref/contrib/admin/#modeladmin-methods )
Cheers!
Hi, take a look at this resolution:
from django.contrib.auth.models import User
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'publisher':
kwargs['queryset'] = User.objects.all()
kwargs['initial'] = request.user.id
return db_field.formfield(**kwargs)
return super(ArticleAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
metamatik's solution (the recommended one by the look of it) is right and works perfectly. Just implement the save_model method and you have access to all the info one might need.
The original article helped me when I needed to alter a choice field that was not a foreign key field, so while the formfield_for_foreignkey is the right way to set the publisher, the initial article helped me get the right choices to another field based on the current user. Thanks.