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

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

ただいまの
回答率

87.80%

djangoオブジェクトの有無を判定し、画面遷移する

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 512

score 6

前提・実現したいこと

django初心者です。
1対1のユーザーテーブルと企業テーブルを作成しています。
ユーザーはdjango-allauthを使用しています。
ユーザーが企業登録をしていれば、詳細表示のDetailViewに、
していなければ新規作成のCreateViewに遷移する機能を作成したいです。

・models.py

class Company(models.Model):
    user = models.ForeignKey(CustomUser,verbose_name='ユーザー名',on_delete=models.PROTECT)
    company_name = models.CharField(verbose_name='会社名',max_length=50, blank=True, null=True)
    department = models.CharField(verbose_name='部署名',max_length=100, blank=True, null=True)
    charge_of_person = models.CharField(verbose_name='ご担当者様',max_length=50, blank=True, null=True)
    postal_code = models.CharField(verbose_name='郵便番号',max_length=50, blank=True, null=True)
    address1 = models.CharField(verbose_name='住所1',max_length=100, blank=True, null=True)
    address2 = models.CharField(verbose_name='住所2',max_length=100, blank=True, null=True)
    email = models.CharField(verbose_name='メールアドレス',max_length=50, blank=True, null=True)
    tel = models.CharField(verbose_name='電話番号',max_length=50, blank=True, null=True)
    fax = models.CharField(verbose_name='FAX番号',max_length=50, blank=True, null=True)
    created_date = models.DateTimeField(auto_now_add = True)
    updated_date = models.DateTimeField(auto_now = True)


・urls.py

from django.urls import path

from . import views

app_name = 'appname'

urlpatterns=[
    path('',views.IndexView.as_view(),name = 'index'),
    path('company_detail/<int:pk>',views.CompanyDetailView.as_view(),name = 'company_detail'),
    path('company_create/',views.CompanyCreateView.as_view(), name='company_create'),


・views.py

from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse,reverse_lazy
from django.views import generic
from .models import Company

class IndexView(LoginRequiredMixin,generic.TemplateView):
    template_name = 'index.html'

    def get(self, request, **kwargs):
        try:
            company = Company.objects.get(user = self.request.user)

        except company.DoesNotExist:
            return reverse('appname:company_create')

        return reverse('appname:company_detail', kwargs={'pk': company.id})

発生している問題・エラーメッセージ

local variable 'company' referenced before assignment

試したこと

・view.py

class IndexView(LoginRequiredMixin,generic.TemplateView):
    template_name = 'index.html'

    def get(self, request, **kwargs):
        try:
            company = Company.objects.get(user = 1)# ← 1を入れてみました

        except company.DoesNotExist:
            return reverse('appname:company_create')

        return reverse('appname:company_detail', kwargs={'pk': company.id})


エラー

'str' object has no attribute 'get'


わからないこと
1.self.request.userをどこで取得したらいいのか
2.オーバーライドするメソッドはgetでいいのか
他に良い書き方があればご教授頂きたいと思います。
よろしくお願いします。

補足情報(FW/ツールのバージョンなど)

django=2.2
pyhton=3.8
mysql=14.14 Distrib 5.7.31

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

下記のようにしてみました。
.exists()関数を使用しています。

# views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseRedirect
# from django.shortcuts import redirect  # HttpResponseRedirectの代わりにredirect()関数を使うときのimport
from django.urls import reverse,reverse_lazy
from django.views import generic
from .models import Company

class IndexView(LoginRequiredMixin,generic.TemplateView):
    template_name = 'index.html'

    def get(self, request, **kwargs):
        user = self.request.user
        if Company.objects.filter(user=user).exists():
            company = Company.objects.get(user=user)
            return HttpResponseRedirect(reverse('appname:company_detail', kwargs={'pk': company.id}))
            # 短縮して下記のような書き方もできます、(冒頭でredirect()関数をimportする必要あり)
            # return redirect('appname:company_detail', pk=company.id)
        return HttpResponseRedirect(reverse('appname:company_create'))
        # 短縮して下記のような書き方もできます。
        # return redirect('appname:company_create')

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/10/07 05:55

    試してみましたが、エラーが出てしまいます。
    企業情報を登録してある場合もしていない場合も以下が表示されます。
    エラー:'str' object has no attribute 'get'
    試しに企業情報を複数件(2件)持たせたデータを作ってみました。
    その場合は
    エラー:get() returned more than one PostedCompany -- it returned 2!
    となります。
    どうぞよろしくお願い致します。

    キャンセル

  • 2020/10/10 01:20

    修正しました。

    キャンセル

  • 2020/10/12 08:20

    ありがとうございます!
    出来ました。
    書き方も丁寧に教えていただき、感謝しています。

    キャンセル

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

  • ただいまの回答率 87.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る