Джанго проблемы с сохранением м2м отношений - PullRequest
1 голос
/ 04 октября 2011

В прошлом мне удавалось сохранить отношения m2m с формами, но в настоящее время у меня возникают проблемы со следующим, и я не могу понять, почему:

# models.py

class File(models.Model):
    client = models.ManyToManyField(Client)
    product = models.ForeignKey(Product, related_name='item_product')
    created = models.DateTimeField(default=datetime.now)
    created_by = models.ForeignKey(User)

# forms.py

class FileForm(ModelForm):

    class Meta:
        model = File
        exclude = ('client')

    def CustomSave(self,product,client,user):
        temp = self.save(commit=False)
        temp.product = product
        temp.client = client   # < ?!?!
        temp.created_by = user
        temp.save()
        temp.save_m2m()
        return temp

# views.py

def new_client_view(request):

    if request.method == 'POST':
        try:
            i_product = int(request.POST['product'])
        except ValueError:
            raise Http404()
        # get a 'product' from the POST data
        p = Product.objects.get(id=i_product)

        formFile = FileForm(p, request.POST, auto_id='f_%s')
        formItemData = ItemDataForm(p, request.POST, auto_id='i_%s')

        if formFile.is_valid() and formItemData.is_valid():
            c = Client()
            c.save()
            tempFile = formFile.CustomSave(p,c,request.user)
            tempItem = ItemForm().CustomSave(tempFile,request.user)
            formItemData.CustomSave(tempItem,request.user)
            return redirect(client_view, c.id)
        else:
            return render_to_response('newClient.html', {'error':'The form was not valid'}, context_instance=RequestContext(request))
     else:
        return render_to_response('newClient.html', {}, context_instance=RequestContext(request))

Когда я пробую вышеупомянутое, я получаю:

'File' instance needs to have a primary key value before a many-to-many relationship can be used.

И django указывает, что ошибка исходит от temp.client = client

Я пробовал различные перестановки CustomSave без особого успеха: (

Есть идеи?

Ответы [ 2 ]

3 голосов
/ 04 октября 2011

Вы пытаетесь назначить одного клиента в поле ManyToMany. Это сработало бы, если бы это был ForeignKey для Клиента, но для ManyToMany вам нужно будет сделать что-то вроде:

temp.client.add(client)

Примечание: temp необходимо сохранить в первую очередь, прежде чем вы сможете назначать клиентов. Это потому, что есть таблица, в которой Django использует сопоставление клиентов с файлами, и если файл не существует, вы не можете добавить строку с нулевым ключом. Глядя на структуру таблицы, которую генерирует Django, следует прояснить ситуацию.

2 голосов
/ 04 октября 2011

Вы пытаетесь сохранить отношения m2m до того, как сам объект был сохранен (commit = False).Чтобы создать связь между клиентом и файлом, файл должен быть сохранен первым.

См. Здесь: Django: экземпляр должен иметь значение первичного ключа перед отношением "многие ко многим"

...