2016-12-28 2 views
0

私は各投稿を投稿したログインしたユーザーと接続したいと思っています。djangoに外部キーで投稿したユーザーに各投稿をマップしますか?

models.py

from django.conf import settings 
from django.db import models 

# Create your models here. 
class Campagin(models.Model): 
    user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1) 
    title = models.CharField(max_length=120) 
    media = models.FileField() 
    description = models.TextField(max_length=220) 
    timestamp = models.DateTimeField(auto_now=False, auto_now_add=True) 
    updated = models.DateTimeField(auto_now=True, auto_now_add=False) 

    def __str__(self): 
     return self.title` 

あなたはポストは、2人の異なるユーザーによって作られた見ることができますが、関係は、それが最初のユーザーimage

このイメージで作られていることを示し登録ユーザーを示していたよう... image

Views.py

class NewCampagin(LoginRequiredMixin, CreateView): 
    template_name = 'campagin/new_campagin.html' 
    model = Campagin 
    fields = ['title','media','description'] 

    def get_absolute_url(self): 
     return reverse('campagin:active_campagin') 
+0

問題: – thebjorn

+0

問題は、 'user_id'は常にデフォルト値' 1'を持っているようです。あなたはキャンペーンのインスタンスを作成するコードを投稿できますか? – dahrens

+0

フォームクラスを投稿できますか? –

答えて

0

さて、CreateViewmodelfieldsの属性をに暗黙的に指定することができます。フォームを作成します。あなたのケースでは、Campaignオブジェクトをデータベースに保存する前に(現在のユーザをログインさせて、ユーザをログインさせる)、いくつかのカスタマイズを行う必要があります。

その結果、あなたが最初に独自のフォームを作成する必要があります(あなたのviews.pyの隣にすることができforms.pyという名前のファイルを作成する)と、このコードを入力します:

class CampaignForm(ModelForm): # Import ModelForm too. 

    def __init__(self, *args, **kwargs): 
     # We need to get access the currently logged in user so set it as an instance variable of CampaignForm. 
     self.user = kwargs.pop('user', None) 
     super(CampaignForm, self).__init__(*args, **kwargs) 

    class Meta: 
     model = models.Campaign # you need to import this from your models.py class 
     fields = ['title','media','description'] 

    def save(self, commit=True): 
     # This is where we need to insert the currently logged in user into the Campaign instance. 

     instance = super(CampaignForm, self).save(commit=False) 

     # Once the all the other attributes are inserted, we just need to insert the current logged in user 
     # into the instance. 
     instance.user = self.user 

     if commit: 
      instance.save() 
     return instance 

今、私たちは私たちのforms.pyすべてを持っていること行く準備ができて、私たちは自分のviews.pyを変更する必要があります

class NewCampagin(LoginRequiredMixin, CreateView): 

    template_name = 'campagin/new_campagin.html' 
    form_class = forms.CampaignForm # Again, you'll need to import this carefully from our newly created forms.py 
    model = models.Campaign # Import this. 
    queryset = models.Campaign.objects.all() 

    def get_absolute_url(self): 
     return reverse('campagin:active_campagin') # Sending user object to the form, to verify which fields to display/remove (depending on group) 

    def get_form_kwargs(self): 
     # In order for us to access the current user in CampaignForm, we need to actually pass it accross. 
     # As such, we do this as shown below. 
     kwargs = super(NewCampaign, self).get_form_kwargs() 
     kwargs.update({'user': self.request.user}) 
     return kwargs 

実際にボンネットの下に私のPOSTリクエストで何が起こっています?

注:これは、学習のためだけの追加情報です。 あなたのクラス ベースビューが実際にあなたの投稿要求をどのように処理しているか気にしない場合、この部分を読む必要はありません。

基本的に

CreateViewは次のようになります。

class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView): 
    """ 
    View for creating a new object instance, 
    with a response rendered by template. 
    """ 
    template_name_suffix = '_form' 

はその面白そうに見えるしませんが、我々はBaseCreateView分析する場合:

class BaseCreateView(ModelFormMixin, ProcessFormView): 
    """ 
    Base view for creating an new object instance. 

    Using this base class requires subclassing to provide a response mixin. 
    """ 


    def post(self, request, *args, **kwargs): 
     self.object = None 
     return super(BaseCreateView, self).post(request, *args, **kwargs) 

を我々は2つの非常に重要なクラスから継承されて見ることができますModelFormMixinおよびProcessFormView。さてライン、return super(BaseCreateView, self).post(request, *args, **kwargs)は、基本的に次のようになりますProcessFormViewpost関数を呼び出します:あなたが見ることができるように

def post(self, request, *args, **kwargs): 
     """ 
     Handles POST requests, instantiating a form instance with the passed 
     POST variables and then checked for validity. 
     """ 
     form = self.get_form() 
     if form.is_valid(): 
      return self.form_valid(form) 
     else: 
      return self.form_invalid(form) 

を、あなたのCreateViewは本当にただ単に指定されたフォームとを検証+を取得し、この小さなpost関数に帰着しますそれを保存します。この時点で2つの質問があります。

1)私も自分のフォームを指定していないので、form = self.get_form()は何をしますか?

2)self.form_valid(form)、実際には何をしているのですか?

self.get_form()は基本的に別の関数form_class = self.get_form_class()を呼び出し、この関数は実際にModelFormMixin(から継承された1!)で発見され、最初の質問に答えるために:

def get_form_class(self): 
    """ 
    Returns the form class to use in this view. 
    """ 
    if self.fields is not None and self.form_class: 
     raise ImproperlyConfigured(
      "Specifying both 'fields' and 'form_class' is not permitted." 
     ) 
    if self.form_class: 
     return self.form_class 
    else: 
     if self.model is not None: 
      # If a model has been explicitly provided, use it 
      model = self.model 
     elif hasattr(self, 'object') and self.object is not None: 
      # If this view is operating on a single object, use 
      # the class of that object 
      model = self.object.__class__ 
     else: 
      # Try to get a queryset and extract the model class 
      # from that 
      model = self.get_queryset().model 

     if self.fields is None: 
      raise ImproperlyConfigured(
       "Using ModelFormMixin (base class of %s) without " 
       "the 'fields' attribute is prohibited." % self.__class__.__name__ 
      ) 
     # THIS IS WHERE YOUR FORM WAS BEING IMPLICITLY CREATED. 
     return model_forms.modelform_factory(model, fields=self.fields) 

あなたが見ることができるように、この関数がありますあなたのフォームは暗黙のうちにが作成されました(最後の行を参照)。お客様のケースに機能を追加する必要がありましたので、forms.pyを作成し、views.pyform_classと指定しました。だからここ

def form_valid(self, form): 
    """ 
    If the form is valid, save the associated model. 
    """ 
    # THIS IS A CRUCIAL LINE. 
    # This is where your actual Campaign object is created. We OVERRIDE the save() function call in our forms.py so that you could link up your logged in user to the campaign object before saving. 
    self.object = form.save() 
    return super(ModelFormMixin, self).form_valid(form) 

我々は単にオブジェクトを保存されています

は、2番目の質問に答えるために、我々は、関数で( self.form_valid(form))コールのソースコードを見てする必要があります。

私はこれがあなたを助けてくれることを願っています!

詳細情報https://docs.djangoproject.com/en/1.10/ref/class-based-views/generic-editing/#createview

+0

エラーが発生します。** NewCampaginにはQuerySetがありません。 NewCampagin.model、NewCampagin.querysetを定義するか、NewCampagin.get_queryset()をオーバーライドしてください。** Exception Type:/ campagin/new/ に正しく設定されていません。例外値:NewCampaginにQuerySetがありません。 NewCampagin.model、NewCampagin.querysetを定義するか、NewCampagin.get_queryset()をオーバーライドします。 –

+0

ああ、単にform_classインスタンス変数の下にqueryset = models.Campaign.objects.all()を追加してください。それを指摘してくれてありがとう。 –

+0

"" "を除いたModelFormMixin(%sの基本クラス)を使用すると、 'fields'属性は使用できません。 iこのエラーが発生しました。 –

関連する問題