を持っていない私は、次の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
'production'クラスはありますか? –
私の質問を、 'models.py'の下の' Production'クラスで更新しました。ありがとう! – wlmrlsda
生産は大文字にする必要がありますか? –