質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

ORM

ORM(オブジェクト関係マッピング)はオブジェクト指向のシステムとリレーショナルデータベースの間でマッピングを行う技術です。

Q&A

解決済

1回答

861閲覧

prefetch_relatedでManyToManyのfieldのレコードを削除したいです。

sususu

総合スコア99

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

ORM

ORM(オブジェクト関係マッピング)はオブジェクト指向のシステムとリレーショナルデータベースの間でマッピングを行う技術です。

0グッド

0クリップ

投稿2019/09/17 15:06

表題の件の通りなのですが、prefetch_relatedを使用いしてJOINしたのちに指定したレコードを削除したいと思っております。
selectは思った動きをしているのですが、deleteがうまく削除されません。
どなたかご教授願えますでしょうか。

selectは下記の通りのコードです。

if_favorite = Favorite.objects.prefetch_related('propertys').all().filter(user_id = login_user_id, propertys = property['id']).values()

上記で発行されるクエリは下記のとおりです。

SELECT `mutual_favorite`.`id`, `mutual_favorite`.`user_id` FROM `mutual_favorite` INNER JOIN `mutual_favorite_propertys` ON (`mutual_favorite`.`id` = `mutual_favorite_propertys`.`favorite_id`) WHERE (`mutual_favorite_propertys`.`property_id` = 12 AND `mutual_favorite`.`user_id` = 1)

上記のコードで発行されるSQLを「select *」 に、「where句も削除」しすべてを表示した結果が下記のとおりです。

+----+---------+----+-------------+-------------+ | id | user_id | id | favorite_id | property_id | +----+---------+----+-------------+-------------+ | 18 | 1 | 36 | 18 | 8 | | 18 | 1 | 37 | 18 | 12 | +----+---------+----+-------------+-------------+

where句の「user_id」で「user_id」を指定しています。
where句の「propertys」で「property_id」を指定しています。
上のクエリを実行するとしっかり下段の結果を取得できるところまでは確認が取れております。

そこで上記のクエリをデリートに変更しようと下記の通りに変更してみます。

Favorite.objects.prefetch_related('propertys').filter(user_id = 1, propertys = 8).delete()

すると実行されるのDELETEのクエリは全てで下記の2件でした

DELETE FROM `mutual_favorite_propertys` WHERE `mutual_favorite_propertys`.`favorite_id` IN (18)
ELETE FROM `mutual_favorite` WHERE `mutual_favorite`.`id` IN (18)

modelは下記のとおりです。

class Property(models.Model): title = models.CharField(max_length=50, blank=False) comment = models.CharField(max_length=300, blank=False) image = models.ImageField(upload_to='photos') vacant_mon = models.BooleanField(default=False) vacant_tue = models.BooleanField(default=False) vacant_wed = models.BooleanField(default=False) vacant_thu = models.BooleanField(default=False) vacant_fri = models.BooleanField(default=False) vacant_sat = models.BooleanField(default=False) vacant_sun = models.BooleanField(default=False) place = models.CharField(max_length=50, blank=False) price = models.PositiveSmallIntegerField(blank=False) create_date = models.DateTimeField(auto_now=True) user = models.ForeignKey(User, on_delete=models.CASCADE) category = models.ForeignKey(Category, on_delete=models.PROTECT) def __str__(self): return self.title class Favorite(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name = "favorite_user") propertys = models.ManyToManyField(Property, blank=True, related_name = "favorite_propertys")

実行される結果が違く困っております。all()をつけてみたり手前にdelete()をつけてみたりしましたがやはりできませんでした。かれこれ何時間もはまっております。この部分が解ければ前回の質問も解決方法を記載できそうなのですが…

どなたかご教授願えませんでしょうか。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

ManyToManyテーブルはインサートはaddデリートはremoveを使用するとのことでした。
joinを使用せずに下記の通りクエリを二回発行する事で対応することにしました。

デリートする場合

login_user_id = request.user.id property_id = request.POST.get("property_id",'nothing') f = Favorite.objects.get(user_id = login_user_id) p = Property.objects.get(id = property_id) result = f.propertys.remove(p)

インサートする場合

login_user_id = request.user.id property_id = request.POST.get("property_id",'nothing') f = Favorite.objects.get(user_id = login_user_id) p = Property.objects.get(id = property_id) result = f.propertys.add(p)

投稿2019/09/29 08:32

sususu

総合スコア99

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問