Форма администратора Django - как динамически изменять выбранные параметры? - PullRequest
5 голосов
/ 24 мая 2011

У меня есть 2 модели:

class City(models.Model):
    name = models.CharField(max_length=50)
    slug = models.SlugField(max_length=50)


class CityNews(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100)
    add_date = models.DateTimeField(auto_now=False, auto_now_add=True, editable=False)
    content = models.TextField()
    city = models.ForeignKey(City)

Каждый мой пользователь был связан с 1 городом. Я хочу, чтобы он добавил новости только в тот город, с которым он связан. Но у суперадмина должна быть возможность добавлять новости в каждый город. Как изменить поле 'city' в CityNews, чтобы в нем отображался только город, с которым связан пользователь? Я могу написать собственный ModelForm, но как я могу проверить там user_city и изменить его набор запросов?

1 Ответ

9 голосов
/ 25 мая 2011

Один очевидный способ сделать это - использовать метод formfield_for_foreignkey () в ModelAdmin.

Так что, если ваш models.py выглядит так:

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

class City(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

class CityNews(models.Model):
    added_by = models.ForeignKey(User)
    city = models.ForeignKey(City)
    title = models.CharField(max_length=100)
    content = models.TextField()

class UserExtra(models.Model):
    user = models.ForeignKey(User)
    city = models.ForeignKey(City)

Тогда ваш admin.py может выглядеть так:

from django.contrib import admin
from formtesting.models import City, CityNews, UserExtra
from django.forms.models import ModelChoiceField
from django.contrib.auth.models import User

class CityAdmin(admin.ModelAdmin):
    pass

admin.site.register(City, CityAdmin)

class CityNewsAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "city":
            if request.user.is_superuser:
                queryset = City.objects.all()
            else:
                queryset = City.objects.filter(userextra__user=request.user)
            return ModelChoiceField(queryset, initial=request.user)
        elif db_field.name == "added_by":
            if request.user.is_superuser:
                queryset = User.objects.all()
            else:
                queryset = User.objects.filter(id=request.user.id)
            return ModelChoiceField(queryset, initial=request.user)
        else:
            return super(CityNewsAdmin, self).formfield_for_foreignkey(db_field, 
                                                              request, **kwargs)

admin.site.register(CityNews, CityNewsAdmin)

class UserExtraAdmin(admin.ModelAdmin):
    pass

admin.site.register(UserExtra, UserExtraAdmin)
...