I'm creating a voting app that makes use of the admin panel (along with django-guardian), where the relevant chain of ForeignKeys between the models is:
Vote =>
Choice (the choice being voted on) =>
Survey (the survey containing the choice) =>
User (the creator of the survey)
Desired behavior:
- When modifying an existing vote for a survey, the admin should only be presented with choices from that particular survey.
- When adding a new vote, the admin should be presented with all choices from all surveys that they have created, in the format "choice.choice_text (survey.question)".
The below code almost gets me where I need to be, except for a few things (in order of importance to me):
- Obviously, temp_creator needs to instead invoke the owner of the survey, i.e. the currently-logged-in user (request.user?).
- When editing an individual vote, I want the choice list restricted to the particular survey that the vote belongs to.
- When adding a new vote via the admin panel, I want all choices to be visible, but I'd like to append the survey.question to them so users can tell which survey they come from, in case surveys share the same choice_text.
Here's my code:
# admin.py
class VoteForm(forms.ModelForm):
temp_creator = User.objects.get(pk=2)
surveys_owned = Survey.objects.filter(creator=temp_creator)
choice = forms.ModelChoiceField(queryset=Choice.objects.filter(survey__in=surveys_owned))
class Meta:
model = Vote
class VoteAdmin(GuardedModelAdmin):
fieldsets = [
('Required fields', {'fields':['voter_name','choice','rank']}),
]
#these lines are for how it's displayed in the admin panel
list_display = ('voter_name','user_name','choice','rank','date_modified','date_created')
list_filter = ['choice','rank','date_modified']
search_fields = ['choice','voter_name','user_name']
form = VoteForm
def queryset(self, request):
if request.user.is_superuser:
return super(VoteAdmin, self).queryset(request)
return get_objects_for_user(user=request.user, perms=['add_vote', 'change_vote', 'delete_vote'], klass=Vote, any_perm=True)
def save_model(self, request, obj, form, change):
"""When creating a new object, set the creator field.
"""
if not change:
obj.user_name = request.user
obj.save()