Администратор Django обрабатывает отношения один ко многим - PullRequest
0 голосов
/ 01 августа 2010

У меня есть модель django, как показано ниже

class Project(models.Model)
      name=models.CharField(max_length=200)

class Application(models.Model)
      proj=models.ForeignKey(Project, null=True, blank=True)

Мне нужно изменить форму администратора проекта, чтобы иметь возможность назначать несколько приложений для проекта, поэтому в admin.py я создалКласс ModelAdmin для проекта выглядит следующим образом

class ProjectAdmin(ModelAdmin)
      form=projectForm
      project_apps=[]

, а форма проекта выглядит следующим образом

class ProjectForm(forms.ModelForm):
    class Meta:
       model = Project

    project_apps =forms.ModelMultipleChoiceField(queryset=Application.objects.all(),required=False,)
def __init__(self, *args, **kwargs):
    super(ProjectForm, self).__init__(*args, **kwargs)
    if self.instance.id is not None:
        selected_items = [ values[0] for values in Application.objects.filter(project=self.instance) ]
        self.fields['project_apps'].initial = selected_items

def save(self,commit=True):
    super(ProjectForm,self).save(commit)
    return self.instance

. Для этого у меня есть множественный выбор в форме создания / редактирования проекта.что мне нужно переопределить метод сохранения, чтобы сохранить ссылку на проект в выбранных приложениях?

как я могу получить выбранные приложения ????

1 Ответ

0 голосов
/ 02 августа 2010

Не совсем уверен, что вы пытаетесь сделать, но, может быть, это?

def save(self,commit=True):
    kwargs.pop('commit') # We're overriding this with commit = False
    super(ProjectForm,self).save(commit)
    if self.instance:
        for a in self.cleaned_data['project_apps']:
            a.proj = self.instance
            a.save()
    return self.instance

Теперь я не могу вспомнить, если в этом случае self.cleaned_data['project_apps'] будет фактически содержать список Application объекты или нет.Я подозреваю, что так и будет, но если нет, то эта функция позаботится об этом:

def clean_project_apps(self):
    app_list = self.cleaned_data['project_apps']
    result = []
    for a in app_list:
        try:
            result.append(Application.objects.get(pk=a)
        except Application.DoesNotExist:
            raise forms.ValidationError("Invalid application record") # to be safe
    return result

В целом, я думаю, что эта форма плохая идея, потому что в основном то, что здесь происходит, это то, что вы отображаете всех записей приложения, которые не имеют смысла, так как большинство из них будут связаны с другими проектами.

О, о, о, о !!!Просто заметил, что вы хотели, чтобы это отображалось в списке множественного выбора!

Вы (вероятно) делаете это неправильно

множественный выбор означает, что это не отношение один ко многим, Это отношения многие-ко-многим.

Это то, что вы хотите сделать, просто peasy, не требует никаких пользовательских форм или что-нибудь .

class Project(models.Model)
      name=models.CharField(max_length=200)
      project_apps = models.ManyToMany('Application', null=True, blank=True)

class Application(models.Model)
      # nothing here (NO foreign key, you want more than one App/Proj and vice versa)

Указание на то, что это поле «многие ко многим» в Project, автоматически создаст поле множественного выбора в admin.Та да!

...