Andreas Neumeier
Andreas Neumeier

Reputation: 326

CreateOrUpdateView for Django Models

In my models I have a ForeignKey relationship like this:

class Question(models.Model):    
    question = models.TextField(null=False)

class Answer(models.Model):                                                    
    question =    models.ForeignKey(Question, related_name='answer')    
    user = models.ForeignKey(User)
    class Meta:
        unique_together = (("question", "user"),)  

the corresponding URL to submit an answer contains the id of the question, like this:

url(r'^a/(?P<pk>\d+)/$', AnswerQuestion.as_view(), name='answer-question'),

With user coming from self.request.user, I am trying to get something like a CreateOrUpdateView, to allow some convenient navigation for the user and URL scheme.

Until now I tried this with:

class AnswerQuestion(LoginRequiredMixin, CreateView):

and add initial value, but that isn't clean because of pk. With an UpdateView I run into problems because I have to set default values for the form.

Has anybody done something like this? I'd rather avoid having a Create and Update view for the same Answer.

Upvotes: 0

Views: 162

Answers (1)

knbk
knbk

Reputation: 53669

The UpdateView and CreateView are really not that different, the only difference is that UpdateView sets self.object to self.get_object() and CreateView sets it to None.

The easiest way would be to subclass UpdateView and override get_object():

AnswerQuestionView(LoginRequiredMixin, UpdateView):
    def get_object(queryset=None):
        if queryset is None:
            queryset = self.get_queryset()

        # easy way to get the right question from the url parameters:
        question = super(AnswerQuestionView, self).get_object(Question.objects.all())

        try:
            obj = queryset.get(user=self.request.user, question=question)
        except ObjectDoesNotExist:
            obj = None
        return obj

Returns the right answer if it exists, None if it does not. Of course add any attributes you need to the class, like model, form_class etc.

Upvotes: 1

Related Questions