Django UpdateView: Object to update has no values

一笑奈何 提交于 2020-01-07 05:28:07

问题


I'd like to update an object with generic view updateview. The problem arises when I edit an object. Instead of reaching a prefilled form, I reach a blank form.
My template for this:

    {% extends 'base.html' %}
    {% block content %}
    <div class="container">
    <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input class="btn btn-danger" type="submit" value="Update" />
    <a  href="{% url 'display_targetbehavior' %}" class="btn btn-default">Take me back</a>
    </form>
    </div>
    {% endblock %}

In my views.py

class HabitUpdate(UpdateView):
    model = Habit
    form_class = HabitForm
    #fields = ('title', 'trigger', 'existingroutine', 'targetbehavior', 'image')
    success_url = reverse_lazy('display_habits')
    template_name = 'habits/update_habit.html'

my model:

class Habit(models.Model):
    AFTER = 'After I'
    WHEN = 'When I'
    WHENEVER = 'Whenever I'
    BEFORE = 'Before I'
    MEANWHILE = 'Meanwhile I'

    TRIGGER_CHOICES = (
      (AFTER, 'After I'),
      (WHEN, 'When I'),
      (WHENEVER, 'Whenever I'),
      (BEFORE, 'Before I'),
      (MEANWHILE, 'Meanwhile I'),
    )

    title = models.CharField(max_length=200)
    trigger = models.CharField(max_length=15, choices=TRIGGER_CHOICES, default=AFTER)
    existingroutine = models.ForeignKey(
      'Existingroutine',
      on_delete=models.SET_NULL,
      blank=True,
      null = True,
    )
    targetbehavior = models.ForeignKey(
      'Targetbehavior',
      on_delete=models.SET_NULL,
      blank=True,
      null = True,
    )

    image = models.ImageField(upload_to='habit_image', blank=True)

    created_by = models.ForeignKey(UserProfile, on_delete=models.SET_NULL, null=True)


    created_at = models.DateTimeField(default=datetime.now, blank=True)

    def __str__(self):
         habitpresentation = self.title# + '\n ' + self.trigger + '\n ' + str(self.existingroutine) + '\n ' + str(self.targetbehavior)
    return habitpresentation

    def image_url(self):
        #print(self.image.url)
        if self.image and hasattr(self.image, 'url'):
            return self.image.url
        else:
            return None;

..and in my forms.py

class HabitForm(forms.ModelForm):
    class Meta:
        model = Habit
        fields = ( 'title', 'trigger', 'existingroutine', 'targetbehavior', 'image')


    def save(self, commit=True):
        habit = super(HabitForm, self).save(commit=False)
        habit.title = self.cleaned_data['title']
        habit.trigger = self.cleaned_data['trigger']
        habit.existingroutine = self.cleaned_data['existingroutine']
        habit.targetbehavior = self.cleaned_data['targetbehavior']
        habit.image = self.cleaned_data['image']

        if commit:
            habit.save()

EDIT urls.py:

from django.conf.urls import include, url

from habits import views as habits_views

urlpatterns = [
    url(r'^$', habits_views.display_habits, name='display_habits'),
    url(r'^habit/details/(?P<id>\w{0,50})/$', habits_views.display_habit_details, name='display_habit_details'),
    url(r'^habit/details/(?P<id>\w{0,50})/delete/$', habits_views.delete_habit, name='delete_habit'),
    #url(r'^habit/details/update/(?P<id>\w{0,50})/$', habits_views.update_habit, name='update_habit'),
    url(r'^habit/details/update/(?P<pk>\w{0,50})/$', habits_views.HabitUpdate.as_view(), name='update_habit'),
    url(r'^habit/create-habit/$', habits_views.create_habit, name='create_habit'),
    url(r'^existingroutines/$', habits_views.display_existing_routines, name='display_existing_routines'),
    url(r'^existingroutines/create/$', habits_views.create_existing_routine, name='create_existing_routine'),
    url(r'^existingroutines/select/(?P<id>\w{0,50})/$', habits_views.select_existing_routine, name='select_existing_routine'),
    url(r'^existingroutines/update/(?P<pk>\w{0,50})/$', habits_views.ExistingroutineUpdate.as_view(), name='update_existing_routine'),
    url(r'^existingroutines/delete/(?P<pk>\w{0,50})/$', habits_views.ExistingroutineDelete.as_view(), name='delete_existing_routine'),
    url(r'^targetbehavior/$', habits_views.display_targetbehavior, name='display_targetbehavior'),
    url(r'^targetbehavior/create/$', habits_views.create_targetbehavior, name='create_targetbehavior'),
    url(r'^targetbehavior/select/(?P<id>\w{0,50})/$', habits_views.select_targetbehavior, name='select_targetbehavior'),
    url(r'^targetbehavior/update/(?P<pk>\w{0,50})/$', habits_views.TargetbehaviorUpdate.as_view(), name='update_targetbehavior'),
    url(r'^targetbehavior/delete/(?P<pk>\w{0,50})/$', habits_views.TargetbehaviorDelete.as_view(), name='delete_targetbehavior'),
]

With this url I'm going to update the habit:

url(r'^habit/details/update/(?P<pk>\w{0,50})/$', habits_views.HabitUpdate.as_view(), name='update_habit'),

EDIT get_object delivers object.

Any suggests?


回答1:


I think your UpdateView is not returning the right object for your template. Have you tried this:

class HabitUpdate(UpdateView):
    model = Habit
    form_class = HabitForm
    template_name = 'habits/update_habit.html'
    success_url = reverse_lazy('display_habits')

    def get_initial(self):
        initial = super(HabitUpdate, self).get_initial()
        print('initial data', initial)

        # retrieve current object
        habit_object = self.get_object()

        initial['field1'] = habit_object.field1
        initial['field2'] = habit_object.field2
        ....
        ....
        return initial


    def get_object(self, *args, **kwargs):
        habit = get_object_or_404(Habit, pk=self.kwargs['pk'])

        return habit

And you only need this in your forms.py file:

class HabitForm(forms.ModelForm):
    class Meta:
        model = Habit
        fields = ( 'title', 'trigger', 'existingroutine', 'targetbehavior', 'image')


来源:https://stackoverflow.com/questions/44259552/django-updateview-object-to-update-has-no-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!