0

を持っていない私は、次のAttributeErrorを取得しています:ジャンゴ:はAttributeError - 「Unicodeの」オブジェクトが属性「ステータス」

Environment: 


Request Method: POST 
Request URL: http://192.168.33.10.xip.io:8000/episodeclicktotweet/2/ 

Django Version: 1.9 
Python Version: 2.7.6 
Installed Applications: 
('producer', 
'django.contrib.admin', 
'registration', 
'django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.messages', 
'django.contrib.staticfiles', 
'storages', 
'django_extensions', 
'randomslugfield', 
'adminsortable2', 
'crispy_forms', 
'charsleft_widget') 
Installed Middleware: 
('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', 
'django.middleware.security.SecurityMiddleware') 



Traceback: 

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

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

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

File "/home/vagrant/fullcast_project/producer/views/views.py" in dispatch 
    97.   return super(ProductionRequiredMixin, self).dispatch(request, *args, **kwargs) 

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

File "/home/vagrant/fullcast_project/producer/views/views.py" in post 
    1141.     autogenerate_click_to_tweet_if_needed(tweet) 

File "/home/vagrant/fullcast_project/producer/helpers/__init__.py" in autogenerate_click_to_tweet_if_needed 
    63.  meets_criteria = production.status() == 'Published' 

Exception Type: AttributeError at /episodeclicktotweet/2/ 
Exception Value: 'unicode' object has no attribute 'status' 

私は、ユーザーが入力彼のツイートのテキストことができますフィールドを持っており、提出このフォームを持っていますそれ。それはDBに入るでしょうがそれはそれです。ただし、クリックトゥウィートリンクと、作成したばかりのリンクが表示される追加のフィールドを生成できる追加のボタンが必要です。

:リンクを自動生成します私の __init__.py次のような方法でフォルダ、私は私の ヘルパーで

if not tweet_ctt_link: 
    autogenerate_click_to_tweet_if_needed(tweet) 
    ProductionTweet.click_to_tweet_link(self) 
    ProductionTweet.click_to_tweet_link = tweet_ctt_link 
    tweet_ctt_link.save() 

この

は私が私のviews.py内のリンクを生成するために実装しようとしていますものです
def autogenerate_click_to_tweet_if_needed(production): 
    """ 
    # We check if the click to tweet associated with this production 
    # needs to be auto-generated. We only do this if it is NULL or empty 
    # so that if user entered it manually it prevales. 
    :param production: 
    """ 
    if not production: 
     return 

    # 1. We check if the production meets the requirements for a click to tweet. 
    # If it does not we delete all click to tweet associated with the production. 
    # Criteria is to be Published. 
    meets_criteria = production.status() == 'Published' 
    if not meets_criteria: 
     ClickToTweetProductionTweet.objects.filter(production=production).delete() 
     return 

    # 2. We get the first and only click to tweet for this production. 
    click_to_tweet = ClickToTweetProductionTweet.objects.filter(production=production).first() 
    # If we have a valid text in the tweet, we just return as we will not 
    # modify an existing one. 
    if click_to_tweet and click_to_tweet.tweet: 
     return 

    # 3. We get the format for the tweet from the Podcast. 
    # if we have no valid format then do nothing 
    tweet_format = production.podcast.podcast_click_to_tweet_format 
    if not tweet_format: 
     return 

    # 4. If we do not have a click to tweet we create one. 
    if not click_to_tweet: 
     click_to_tweet = ClickToTweetProductionTweet(production=production) 

    # 5. We will make the necessary an possible substitutions on the format 
    # to compose the tweet text. 
    # Valid placeholders are: 
    # PODCAST_TWITTER_NAME = podcast_twitter_name (in podcast) 
    # PODCAST_GUEST_TWITTER_NAME = podcast_guest_twitter_name (in podcast) 
    # WORDPRESS_URL = wordpress_url (in production) 
    tweet_format = replace_placeholder_in_text_format_with_parameter(tweet_format, 'PODCAST_TWITTER_NAME', 
                     production.podcast.podcast_twitter_name) 
    tweet_format = replace_placeholder_in_text_format_with_parameter(tweet_format, 'PODCAST_GUEST_TWITTER_NAME', 
                     production.podcast.podcast_guest_twitter_name) 
    wordpress_url = production.wordpress_short_url if production.wordpress_short_url else production.wordpress_url 
    tweet_format = replace_placeholder_in_text_format_with_parameter(tweet_format, 'WORDPRESS_URL', wordpress_url) 
    tweet_format = smart_text(tweet_format) 

    # 6. Update and save 
    click_to_tweet.tweet = tweet_format 
    click_to_tweet.save() 

私のProductionTweetクラスはmodels.pyで、私はリンクをつかむことができる次の方法を持っています:

ここ
def click_to_tweet_link(self): 
     base_url = settings.CLICK_TO_TWEET_BASE_URL 
     if not base_url: 
      return None 
     return base_url + self.slug 

views.pyでのつぶやきセクションの図である。ClickToTweetため

class EpisodeClickToTweet(ProductionRequiredMixin, View): 
form_class = EpisodeClickToTweetForm 
template_name = 'fc/forms_clicktotweet.html' 

def get(self, request, *args, **kwargs): 
    initial_values = {} 
    # See if we already have a click to tweet for this production, if so get id 
    click_to_tweet = ClickToTweetProductionTweet.objects.filter(production_id=self.production.id).first() 

    initial_values['production_id'] = self.production.id 
    initial_values['id'] = click_to_tweet.id if click_to_tweet else None 
    initial_values['tweet'] = click_to_tweet.tweet if click_to_tweet else None 

    form = self.form_class(initial=initial_values) 
    return render(request, self.template_name, {'form': form}) 

def post(self, request, *args, **kwargs): 
    form = self.form_class(request.POST) 

    if form.is_valid(): 
     # lets get the data 
     production_id = form.cleaned_data.get('production_id') 
     id = form.cleaned_data.get('id') 
     tweet = form.cleaned_data.get('tweet') 
     tweet_ctt_link = form.cleaned_data.get('tweet_ctt_link') 

     #A production must exist, othewise 404 
     production = get_object_or_404(Production, id=production_id) 

     if id: 
      click_to_tweet = ClickToTweetProductionTweet.objects.get(id=id) 
     else: 
      click_to_tweet = ClickToTweetProductionTweet(production=production) 

     click_to_tweet.tweet = tweet 
     click_to_tweet.save() 

     if not tweet_ctt_link: 
      autogenerate_click_to_tweet_if_needed(tweet) 
      ProductionTweet.click_to_tweet_link(self) 
      ProductionTweet.click_to_tweet_link = tweet_ctt_link 
      tweet_ctt_link.save() 


     return HttpResponseRedirect(reverse('fc:episodeschedule', kwargs={'production_id':production_id})) 

    return render(request, self.template_name, {'form': form}) 

フォーム:

from django import forms 

import django 

if django.VERSION < (1,7): 
    from charsleft_widget.fields import CharField 
else: 
    from django.forms.fields import CharField 

from charsleft_widget import CharsLeftArea 

class EpisodeClickToTweetForm(forms.Form): 
    production_id = forms.IntegerField(widget=forms.Field.hidden_widget, required=False) 
    id = forms.IntegerField(widget=forms.Field.hidden_widget, required=False) 
    tweet = forms.CharField(max_length=120, required=False, 
          widget=CharsLeftArea) 
    tweet_ctt_link = forms.CharField(label='Click To Tweet Link', required=False, 
          widget=forms.TextInput(attrs={'placeholder': 'Click To Tweet link will be generated here',})) 

テンプレート:

{% extends "fc/base.html" %} 
{% load crispy_forms_tags %} 

{% block content %} 

<div class="progress"> 
    <div class="progress-bar progress-bar-striped progress-bar-success active" role="progressbar" aria-valuenow="87.5" aria-valuemin="0" aria-valuemax="100" style="width: 87.5%"> 
    <span class="sr-only">87.5% Complete</span> 
    </div> 
</div> 

<div class="panel panel-default box-shadow--16dp col-sm-6 col-sm-offset-3"> 
<div class="panel-body"> 

<div class='row'> 
<div class='col-sm-12'> 

<h3>Setup | Add Episode</h3> 

<h4>Twitter - Guest Click-To-Tweet</h4> 

<h5>FC will also build the ‘clickable tweet’ which will be automatically sent in the body of the mail to your guest on the morning of the episode goes live.</h5> 

<hr/> 

<form method='POST' action=''>{% csrf_token %} 
{{ form|crispy }} 
<button type="submit" class="btn btn-info box-shadow--6dp"><i class="fa fa-link" aria-hidden="true"></i> Generate Link 
</button> 

<hr/> 
<button type="submit" class="btn btn-primary box-shadow--6dp"><i class="fa fa-chevron-right pull-right"></i> Continue 
</button> 

</form> 

</form> 
</div> 
</div> 

</div> 
</div> 

{% endblock %} 

すべてのヘルプや提案apになるpreciated

------------ UPDATEは-----------フォームで

class Production(TimeStampedModel): 
    BASE_PRODUCTION = 'B' 
    SECONDARY_PRODUCTION = 'S' 

    podcast = models.ForeignKey(Podcast, on_delete=models.SET_NULL, null=True) 
    ready_for_production = models.BooleanField(default=False) 

    episode_number = models.PositiveIntegerField(null=True) 
    episode_title = models.CharField(max_length=255) 
    episode_guest_last_name = models.CharField(max_length=128, null=True, blank=True) 
    episode_guest_first_name = models.CharField(max_length=128, null=True, blank=True) 
    episode_guest_twitter_name = models.CharField(max_length=64, null=True, blank=True) 
    episode_summary = models.TextField(blank=False, null=True) 

    base_production_uuid = models.CharField(max_length=32, null=True, blank=True) 
    base_production_status = models.CharField(max_length=255, blank=True) 
    base_production_produced = models.BooleanField(default=False) 
    base_production_started = models.BooleanField(default=False) 
    base_production_cover_image = models.CharField(max_length=255, null=True) 
    square_image_file = models.ImageField(upload_to='square_image', null=True, blank=True) 

    secondary_production_uuid = models.CharField(max_length=32, null=True, blank=True) 
    secondary_production_status = models.CharField(max_length=255, blank=True) 
    secondary_production_produced = models.BooleanField(default=False) 
    secondary_production_started = models.BooleanField(default=False) 
    secondary_production_cover_image = models.CharField(max_length=255, null=True) 
    banner_image_file = models.ImageField(upload_to='banner_image', null=True, blank=True) 

    auphonic_result_url = models.URLField(null=True, blank=True) 
    soundcloud_result_url = models.URLField(null=True, blank=True) 
    soundcloud_error_message = models.CharField(max_length=100, null=True, blank=True) 
    youtube_result_url = models.URLField(null=True, blank=True) 
    youtube_error_message = models.CharField(max_length=100, null=True, blank=True) 
    libsyn_result_url = models.URLField(null=True, blank=True) 
    libsyn_error_message = models.CharField(max_length=100, null=True, blank=True) 
    spreaker_result_id = models.PositiveIntegerField(null=True) 
    spreaker_result_id_request_attempted = models.BooleanField(default=False) 

    source_file_name = models.CharField(max_length=64, null=True) 
    source_file = models.FileField(upload_to='audio_source', null=True, blank=True) 
    output_base_name = models.CharField(max_length=64, null=True) 

    scheduled_date = models.DateTimeField(null=True, blank=True) 
    time_scheduled = models.CharField(max_length=120, null=True, blank=True) 
    fully_produced_date = models.DateTimeField(null=True, blank=True) 
    auto_email_sent = models.BooleanField(default=False) 

    post_to_wordpress = models.BooleanField(default=True) 
    wordpress_post_id = models.PositiveIntegerField(null=True) 
    wordpress_slug = models.CharField(max_length=127, null=True, blank=True) 
    wordpress_url = models.URLField(null=True, blank=True) 
    wordpress_short_url = models.URLField(null=True, blank=True) 
    wordpress_featured_image = models.CharField(max_length=255, null=True, blank=True) 
    wordpress_featured_image_upload = models.FileField(upload_to='wordpress_image', null=True, blank=True) 
    wordpress_post_unique_tags = models.TextField(null=True, blank=True) 
    wordpress_posting_failure_notified = models.BooleanField(default=False) 

    transcription_url = models.URLField(null=True, blank=True) 

    tweets_already_scheduled = models.BooleanField(default=False) 
    number_of_refresh_tweets = models.PositiveIntegerField(default=0) 
    tweets_scheduling_failure_notified = models.BooleanField(default=False) 
    is_podfunnel = models.BooleanField(default=False) 
    asynch_publish_in_process = models.BooleanField(default=False) 

    def __unicode__(self): 
     return smart_text(self.base_production_episode_title()) 

    def fully_produced(self): 
     return self.base_production_produced and self.secondary_production_produced 
    fully_produced.short_description = 'Produced' 

    def status(self): 
     if not self.fully_produced(): 
      return 'Pending' 
     if self.wordpress_url: 
      return 'Published' 
     return 'Produced' 

    def base_status(self): 
     if not self.base_production_produced: 
      return 'Pending' 
     if self.wordpress_url: 
      return 'Published' 
     return 'Produced' 

    def episode(self): 
     return self.episode_number 

    def base_production_episode_title(self): 
     return self._title_string_for_format(self.podcast.base_production_name_format) 

    def secondary_production_episode_title(self): 
     return self._title_string_for_format(self.podcast.secondary_production_name_format) 

    def _title_string_for_format(self, title_format): 
     from producer.helpers import replace_placeholder_in_text_format_with_parameter 

     guest_name = self.episode_guest() 
     episode_number = str(self.episode_number).zfill(3) 
     episode_title = self.episode_title 

     title = replace_placeholder_in_text_format_with_parameter(title_format, 'EPISODE_GUEST_FULL_NAME', guest_name) 
     title = replace_placeholder_in_text_format_with_parameter(title, 'EPISODE_NUMBER', episode_number) 
     title = replace_placeholder_in_text_format_with_parameter(title, 'EPISODE_TITLE', episode_title) 

     return title 

    def episode_guest(self): 
     if self.episode_guest_last_name and self.episode_guest_first_name: 
      return '%s %s' % (self.episode_guest_first_name, self.episode_guest_last_name) 

     if self.episode_guest_last_name: 
      return self.episode_guest_last_name 

     if self.episode_guest_first_name: 
      return self.episode_guest_first_name 

     return '' 

    def soundcloud_result_link(self): 
     if self.soundcloud_result_url: 
      return '<a href="%s" target="_blank">%s</a>' % (self.soundcloud_result_url, self.soundcloud_result_url) 
     return 
    soundcloud_result_link.allow_tags = True 

    def auphonic_result_link(self): 
     if self.auphonic_result_url: 
      return '<a href="%s" target="_blank">%s</a>' % (self.auphonic_result_url, self.auphonic_result_url) 
     return 
    auphonic_result_link.allow_tags = True 

    def youtube_result_link(self): 
     if self.youtube_result_url: 
      return '<a href="%s" target="_blank">%s</a>' % (self.youtube_result_url, self.youtube_result_url) 
     return 
    youtube_result_link.allow_tags = True 

    def wordpress_link(self): 
     if self.wordpress_url: 
      return '<a href="%s" target="_blank">%s</a>' % (self.wordpress_url, self.wordpress_url) 
     return 
    wordpress_link.allow_tags = True 

    def wordpress_short_link(self): 
     if self.wordpress_short_url: 
      return '<a href="%s" target="_blank">%s</a>' % (self.wordpress_short_url, self.wordpress_short_url) 
     return 
    wordpress_short_link.allow_tags = True 

    def libsyn_result_link(self): 
     if self.libsyn_result_url: 
      return '<a href="%s" target="_blank">%s</a>' % (self.libsyn_result_url, self.libsyn_result_url) 
     return 
    libsyn_result_link.allow_tags = True 

    def transcription_link(self): 
     if self.transcription_url: 
      return '<a href="%s" target="_blank">%s</a>' % (self.transcription_url, self.transcription_url) 
     return 
    transcription_link.allow_tags = True 
+0

'production'クラスはありますか? –

+0

私の質問を、 'models.py'の下の' Production'クラスで更新しました。ありがとう! – wlmrlsda

+0

生産は大文字にする必要がありますか? –

答えて

0

tweetフィールドはCharFieldですです。そのフィールドに入力された値は文字列です。しかし、あなたはそれをstatus()と呼ぶあなたの自動生成ヘルパーにその値を送ります。

代わりにプロダクションインスタンスをそのヘルパーに送信することを意図したようです。

+0

助けてくれてありがとう、だから、その値をヘルパーに送る最良の方法は、リンクを生成して、それを 'tweet_ctt_link'フィールドに送り返すことです。 – wlmrlsda

+0

私は考えていません、ここにはたくさんのコードがあります。あなたが何をしようとしているのかは分かりません。しかし、最初にあなたには 'production'変数があります。多分あなたはそれを 'tweet'の代わりに送るつもりだったでしょうか?ヘルパーから値を「返送」したい場合は、返却する必要があります。 –

関連する問題