Джанго м2м и спасательные объекты - PullRequest
1 голос
/ 03 декабря 2009

У меня есть пара простых объектов, которые имеют отношение многие ко многим. Django присоединился к ним, используя таблицу obj1_obj2, и это выглядит так в mysql;

id  |  person_id  |  nationality_id  
-----------------------------------  
 1  |     1       |      1  
 2  |     1       |      2  

Теперь, когда я сохраняю obj1 (который показывает obj2 как Multi-select в своей форме), идентификаторы в таблице obj1_obj2 увеличиваются, даже если я их не менял. Например, я изменяю базовое символьное поле для obj1 в его форме и сохраняю его, и данные в присоединяющейся таблице, кажется, удаляются и повторно сохраняются, давая записи новые идентификаторы.

На самом деле мне не нужно ничего менять, все, что мне нужно сделать, это сохранить форму, и происходит то же самое.

Все, что я делаю в представлении, это form.save (), ничего особенного. Это нормальный способ, которым он работает?

РЕДАКТИРОВАТЬ: добавлены модели, виды, формы

class Person(models.Model):
    name = models.CharField()  
    birthdate = models.CharField()  
    nationality = models.ManyToMany(Nationality)


class Employee(Person):
    employeeNum = models.CharField()


class FamilyMember(Person):  
    employee = models.ForeignKey(Employee)
    relationship = models.CharField()


class Nationality(models.Model):
    abbrev = models.CharField()
    country = models.CharField()


class FamilyMemberDetailsForm(forms.ModelForm):
    class Meta:
        model = FamilyMemeber
        exclude = ['employee']


def editFamilyMember(request, familyMember_id):
    familyMember = get_object_404(FamilMember, familyMember_id)
    if request.method == 'POST':
        form = FamilyMemberDetailsForm(request.POST, instance=familyMember)
        if form.is_valid():  
          form.save()
    else:
        form = FamilyMemberDetailsForm(instance=familyMember) 


    return render_to_response(editForm.html, {'form':form},  
                              context_instance(RequestContext(request))

Это урезанная версия моделей, но то же самое происходит для сохранения сотрудника или члена семьи. FamilyMember, который я показал, потому что это так просто, я создаю modelForm, а затем вносить изменения и затем сохраняю их. Для сотрудника я делаю еще несколько манипуляций в «1013 * init * 1014» Формы для национальности, главным образом для представления, и сначала я подумал, что именно эта манипуляция и была причиной этого, но, как я сказал, то же самое происходит с FamilyMember, где я ничего не делаю, кроме как сохранить.

Национальность отображается в форме в виде поля с несколькими вариантами выбора, и пользователь может выбрать 1 или более из списка. Если я просто представляю заполненную форму, а затем сохраняю ее, ничего не меняя, меняется идентификатор для записи таблицы «многие ко многим».

Я также изменил названия таблиц примеров.

Спасибо
Andrew

1 Ответ

2 голосов
/ 06 декабря 2009

Да, удаление любых существующих строк в appname_obj1_obj2 является ожидаемым поведением при сохранении формы для объекта, который имеет ManyToManyField.

Вы можете увидеть clear () перед add (** values) в ReverseManyRelatedObjectsDescriptor и ManyRelatedObjectsDescriptor в django / db / models / fields / related.py.

Откройте оболочку и посмотрите сами на запросы. Что-то вроде этого должно показать вам УДАЛЕНИЕ до ВСТАВКИ в raw sql.

from django.db import connection
fm = FamilyMember.objects.get(pk=1)
form = FamilyMemberDetailsForm(instance=fm)
data = form.initial
data['name'] = "z%s" % data['name']  
form = FamilyMemberDetailsForm(data, instance=fm)
connection.queries = []  # clearing to limit the queries you have to look at
form.save()
for q in connection.queries:
    print("%s\n" % q['sql'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...