2016-08-02 4 views
3

Ich erhalte den Fehler angibt:, dachte ich in meinem Code in demEin weiterer nicht-Wert auf einem ManyToManyField einstellen, die einen Vermittler Modell

Cannot set values on a ManyToManyField which specifies an intermediary model. Use ipaswdb.ProviderLocations's Manager instead.

Ich erhalte gestolpert durch den ipaswdb.ProviderLocations Manager Abschnitt views.py Ich habe die M2M-Beziehung meines Modells in form_valid richtig angesprochen.

sah ich das so beantworten: django Cannot set values on a ManyToManyField which specifies an intermediary model. Use Manager instead

Was mich führte eine self.object.save() hinzufügen, aber das scheint nicht getan nichts von. In der UpdateView scheint der Code wie es funktioniert, aber ich gehe zu überprüfen und auch wenn ich zwei Standorte, die über die Druckanweisungen, die ich sehen kann aus dem Formular zurückkommt, nur eins in der Datenbank ...

I sehe diesen Fehler in der CreateView, mit oder ohne die hinzugefügte self.object.save() (Gedanke, ich bekam es, weil das Commit = False und das Objekt wurde noch nicht gespeichert). Ich werde die beteiligten Modelle auch unten hinzufügen, ihre Beziehung ist komplex.

class ProviderCreateView(CreateView): 
    model = Provider 
    form_class = ProviderForm 
    template_name = 'ipaswdb/provider/provider_form.html' 
    success_url = 'ipaswdb/provider/' 

    def form_valid(self, form): 
     self.object = form.save(commit=True) #traceback shows this as offending line 
     ProviderLocations.objects.filter(provider=self.object).delete() 
     self.object.save() 

     for group_location in form.cleaned_data['group_locations']: 
      location = ProviderLocations() 
      location.provider = self.object 
      location.group_location = group_location 
      location.save() 

     return super(ModelFormMixin, self).form_valid(form) 

class ProviderUpdateView(UpdateView): 
    model = Provider 
    form_class = ProviderForm 
    template_name = 'ipaswdb/provider/provider_form.html' 
    success_url = 'ipaswdb/provider/' 


    def form_valid(self, form): 
     self.object = form.save(commit=False) 
     ProviderLocations.objects.filter(provider=self.object).delete() 
     self.object.save() 
     for group_location in form.cleaned_data['group_locations']: 
      print("here!" + self.object.first_name) 
      location = ProviderLocations() 
      location.provider = self.object 
      location.group_location = group_location 
      location.save() 

      return super(ModelFormMixin, self).form_valid(form) 

Dann meine Modelle:

class Provider(models.Model): 
    first_name = models.CharField(max_length = 50) 
    last_name = models.CharField(max_length = 50) 
    date_of_birth = models.DateField(auto_now_add=False) 
    group_locations = models.ManyToManyField('GroupLocations', through='ProviderLocations', blank=True, null=True) 
    etc... 

class ProviderLocations(models.Model): 
     #group_location = models.ForeignKey('GroupLocations', on_delete=models.CASCADE) 
    provider = models.ForeignKey('Provider', on_delete=models.CASCADE) 
    group_location = models.ForeignKey('GroupLocations', on_delete=models.CASCADE) 
    created_at=models.DateField(auto_now_add=True) 
    updated_at=models.DateField(auto_now=True) 
    def __str__(self): 
     return self.provider.first_name 

class GroupLocations(models.Model): 
    address = models.ForeignKey('Address', on_delete= models.SET_NULL, null=True) 
    group = models.ForeignKey('Group', on_delete=models.CASCADE) 
    doing_business_as = models.CharField(max_length = 255) 
    created_at=models.DateField(auto_now_add=True) 
    updated_at=models.DateField(auto_now=True) 
    def __str__(self): 
     return self.doing_business_as 


class Group(models.Model): 
    group_name = models.CharField(max_length=50) 
    etc... 

Ok Debug-Logger drehte den ganzen Weg bis zeigt diese SQL nur eine INSERT tun, wenn die Druck Aussagen zeigen die zahlreichen Standorten es versucht, hinzuzufügen:

0.001) SELECT "ipaswdb_grouplocations"."id", "ipaswdb_grouplocations"."address_id", "ipaswdb_grouplocations"."group_id", "ipaswdb_grouplocations"."doing_business_as", "ipaswdb_grouplocations"."created_at", "ipaswdb_grouplocations"."updated_at" FROM "ipaswdb_grouplocations" WHERE "ipaswdb_grouplocations"."id" IN (3, 2, 5, 4); args=(3, 2, 5, 4) 
(0.000) BEGIN; args=None 
(0.000) DELETE FROM "ipaswdb_providerlocations" WHERE "ipaswdb_providerlocations"."provider_id" = NULL; args=(None,) 
(0.000) BEGIN; args=None 
(0.001) INSERT INTO "ipaswdb_provider" ("first_name", "last_name", "date_of_birth", "license_number", "license_experation", "dea_number", "dea_experation", "phone", "fax", "ptan", "caqh_number", "effective_date", "provider_npi", "provisional_effective_date", "date_joined", "provider_contact", "credentialing_contact", "notes", "hospital_affiliation", "designation_id", "specialty_id", "created_at", "updated_at") VALUES ('Onemore', 'Test', '2016-08-12', 'kljlk', '2016-08-12', 'kljjkl', '2016-08-12', '', '', '', 'lk;fsd', '2016-08-12', 'jksalfas', '2016-08-12', '2016-08-12', 'kj;jasdf', ';kjsfas', '', '', NULL, NULL, '2016-08-12', '2016-08-12'); args=[u'Onemore', u'Test', u'2016-08-12', u'kljlk', u'2016-08-12', u'kljjkl', u'2016-08-12', u'', u'', u'', u'lk;fsd', u'2016-08-12', u'jksalfas', u'2016-08-12', u'2016-08-12', u'kj;jasdf', u';kjsfas', u'', u'', None, None, u'2016-08-12', u'2016-08-12'] 
here!IPAABQ  <-- all the locations to add is with the here! 
here!ststs 
here!2312 
here!fsfd315 
(0.000) BEGIN; args=None 

sehen einen Einsatz

(0.000) INSERT INTO "ipaswdb_providerlocations" ("provider_id", "group_location_id", "created_at", "updated_at") VALUES (22, 5, '2016-08-12', '2016-08-12'); args=[22, 5, u'2016-08-12', u'2016-08-12'] 
[12/Aug/2016 19:46:26] "POST /ipaswdb/provider/add/ HTTP/1.1" 302 0 
(0.001) SELECT COUNT(*) AS "__count" FROM "ipaswdb_provider"; args=() 
(0.000) SELECT "ipaswdb_provider"."id", "ipaswdb_provider"."first_name", "ipaswdb_provider"."last_name", "ipaswdb_provider"."date_of_birth", "ipaswdb_provider"."license_number", "ipaswdb_provider"."license_experation", "ipaswdb_provider"."dea_number", "ipaswdb_provider"."dea_experation", "ipaswdb_provider"."phone", "ipaswdb_provider"."fax", "ipaswdb_provider"."ptan", "ipaswdb_provider"."caqh_number", "ipaswdb_provider"."effective_date", "ipaswdb_provider"."provider_npi", "ipaswdb_provider"."provisional_effective_date", "ipaswdb_provider"."date_joined", "ipaswdb_provider"."provider_contact", "ipaswdb_provider"."credentialing_contact", "ipaswdb_provider"."notes", "ipaswdb_provider"."hospital_affiliation", "ipaswdb_provider"."designation_id", "ipaswdb_provider"."specialty_id", "ipaswdb_provider"."created_at", "ipaswdb_provider"."updated_at" FROM "ipaswdb_provider" LIMIT 3; args=() 
[12/Aug/2016 19:46:26] "GET /ipaswdb/provider/add/ipaswdb/provider/ HTTP/1.1" 200 4835 

Sieht aus wie etwas mit dem Traceback:

Environment: 


Request Method: POST 
Request URL: http://localhost:8001/ipaswdb/provider/add/ 

Django Version: 1.9.5 
Python Version: 2.7.11 
Installed Applications: 
['ipaswdb.apps.IpaswdbConfig', 
'django.contrib.admin', 
'django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.messages', 
'django.contrib.staticfiles'] 
Installed Middleware: 
['django.middleware.security.SecurityMiddleware', 
'django.contrib.sessions.middleware.SessionMiddleware', 
'django.middleware.common.CommonMiddleware', 
'django.middleware.csrf.CsrfViewMiddleware', 
'django.contrib.auth.middleware.AuthenticationMiddleware', 
'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 
'django.contrib.messages.middleware.MessageMiddleware', 
'django.middleware.clickjacking.XFrameOptionsMiddleware'] 



Traceback: 

File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response 
    149.      response = self.process_exception_by_middleware(e, request) 

File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response 
    147.      response = wrapped_callback(request, *callback_args, **callback_kwargs) 

File "/usr/local/lib/python2.7/site-packages/django/views/generic/base.py" in view 
    68.    return self.dispatch(request, *args, **kwargs) 

File "/usr/local/lib/python2.7/site-packages/django/views/generic/base.py" in dispatch 
    88.   return handler(request, *args, **kwargs) 

File "/usr/local/lib/python2.7/site-packages/django/views/generic/edit.py" in post 
    256.   return super(BaseCreateView, self).post(request, *args, **kwargs) 

File "/usr/local/lib/python2.7/site-packages/django/views/generic/edit.py" in post 
    222.    return self.form_valid(form) 

File "/Users/shane.thomas/programming/py3env/ipa_django/mysite/ipaswdb/views.py" in form_valid 
    38.  self.object = form.save(commit=True) 

File "/usr/local/lib/python2.7/site-packages/django/forms/models.py" in save 
    452.    self._save_m2m() 

File "/usr/local/lib/python2.7/site-packages/django/forms/models.py" in _save_m2m 
    434.     f.save_form_data(self.instance, cleaned_data[f.name]) 

File "/usr/local/lib/python2.7/site-packages/django/db/models/fields/related.py" in save_form_data 
    1618.   setattr(instance, self.attname, data) 

File "/usr/local/lib/python2.7/site-packages/django/db/models/fields/related_descriptors.py" in __set__ 
    481.   manager.set(value) 

File "/usr/local/lib/python2.7/site-packages/django/db/models/fields/related_descriptors.py" in set 
    882.      (opts.app_label, opts.object_name) 

Exception Type: AttributeError at /ipaswdb/provider/add/ 
Exception Value: Cannot set values on a ManyToManyField which specifies an intermediary model. Use ipaswdb.ProviderLocations's Manager instead. 
+0

Es gibt nur einen Ort, der [erzeugt diesen Fehler] django (https://github.com/django/django/blob/d30febb4e59b659e0d279c77f61f936c199a05b2/django/db/models/fields/related_descriptors.py#L971) ... I Ich schlage vor, Sie schauen sich Ihren Stack-Trace an und sehen, wie dieser in Ihrem eigentlichen (komplexeren) Code aufgerufen wird ... –

+0

Okay, ich habe das noch einmal gelesen und einen Traceback hinzugefügt, ich bin mir nicht sicher, was es mich auslöst, aber etwas über das Speichern der Formulare . Vielleicht hat das views.py ProviderCreateView (CreateView) ein Problem im form.save (commit = True) Teil, wirklich sieht es tiefer aus. Angesichts des Links, den du gepostet hast, vermute ich, dass der Fehler irgendwie darin liegt, wie meine Modelle definiert sind, wie es aussieht, als ob der Fehler von den related_descritoriors-Sachen kommt. – Codejoy

Antwort

4

nicht begehen Sie, wenn Sie speichern zu speichern. Wie dokumentiert here, wenn Sie 10 angeben, wird es versuchen, das M2M-Mapping gleichzeitig zu schreiben. Du willst nicht, dass das passiert.

Indem Sie stattdessen einen Wert von angeben, können Sie später save_m2m aufrufen, um das Mapping zu speichern oder stattdessen ein eigenes Mapping zu erstellen. Sie müssen Letzteres tun, und der Rest Ihres Codes tut bereits das Richtige dafür.

+0

Das hat den Fehler zwar behoben, aber es speichert immer noch nur einen Eintrag von der Benutzeroberfläche, obwohl ich im Widget zwei Klicks klicke und auf Speichern klicke und verifiziert habe, dass zwei Einträge wieder in der Datei views.py erscheinen. Gibt es mehr Bein, das ich tun muss?Ich frage mich, ob die Linien in der Ansicht erstellen sind nicht zwei Instanzen zu schaffen, sondern über eine Instanz schriftlich erstellt \t \t \t location = ProviderLocations() \t location.provider = self.object – Codejoy

+0

nicht sicher, warum ... Sie könnten versuchen, die Freigabe [SQL backend logger] (https://docs.djangoproject.com/de/1.10/topics/logging/#django-db-backends) um zu sehen, wie djago Ihren Code interpretiert. Möglicherweise müssen Sie [Erzwingen einfügen] (https://docs.djangoproject.com/en/1.10/ref/models/instances/#forcing-an-insert-or-update). –

+0

Nochmals vielen Dank, aktualisiert die Frage mit der neuesten nach dem Drücken des Debug-Systems auf den Bildschirm. Ich kann nicht sagen, ob das ein neues Problem ist (sollte ich nicht wirklich Kabeljau wirklich berührt haben), oder wenn sein Teil von einem, der mich zuerst hierher brachte. Die Frage aktualisiert, um die Ausgabe des letzten Laufs auf Windows hinzuzufügen – Codejoy

Verwandte Themen