2011-05-23 31 views
5

tengo 2 modelos:Formulario de administración de Django: cómo cambiar las opciones de selección de forma dinámica?

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) 

Mi cada usuario se ha conectado con 1 ciudad. Quiero que agregue noticias solo a la ciudad con la que se conectó. Pero la superadmina debe tener la posibilidad de agregar noticias a cada ciudad. ¿Cómo puedo cambiar el campo 'ciudad' en CityNews, que muestran solo la ciudad con la que está conectado el usuario? Puedo escribir ModelForm personalizado, pero ¿cómo puedo verificar user_city allí y cambiar su queryset?

+0

¿Hay una razón por la que usted no aceptó la respuesta? Sólo me preguntaba. –

+0

No, lo olvidé :) – robos85

Respuesta

9

Una forma obvia de hacerlo es utilizar el método formfield_for_foreignkey() en ModelAdmin.

Así que si su models.py se parece a esto:

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) 

Luego, su admin.py podría tener este aspecto:

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) 
+0

Funciona muy bien, pero no devuelve verbose_name del modelo. En cambio, muestra el nombre de campo otiginal. ¿Sabes por qué? – robos85

+0

Lejos de la computadora, pero intente utilizar la etiqueta como una palabra clave arg para ModelChoiceField? –

+0

Utilicé label = base_class_db_field.verbose_name.capitalize() y funciona como un hechizo – robos85

Cuestiones relacionadas