Django: How do you associate an Object_PK in the URL to the Foreign_Key relation field when creating a new object?
<p>I am building an FAQ system. The models extend from Topic -> Section -> Article. When creating a new Article the User will select a Topic then a Section then the create Article button.</p>

<p>The url will look something like //mysite.org/Topic_PK/Section_PK/Article_Create</p>

<p>In Django it should look like this: </p>

<pre><code>url(r'^ironfaq/(?P&lt;pk&gt;\d+)/(?P&lt;pk&gt;\d+)/article$', ArticleCreateView.as_view(), name=âarticle-createâ)
</code></pre>

<p>What I am looking to do is to associate the Section_PK to the Article when the user submits the Article. I have the Section_PK in the URL I need help to figure out how to use it to do this.</p>

<p>Alternatively with this set up I can have a form rendered with a choice selection from the Section_FK in the Articles Model. If when creating the Article upon rendering the template if I could limit the Section choices by the Topic in the form.py this will also work for my needs</p>

<p>The url will look something like //mysite.org/Topic_PK/article/create</p>

<p>In Django the url should look like this:</p>

<pre><code>url(r'^ironfaq/(?P&lt;pk&gt;\d+)/article/create$', ArticleCreateView.as_view(), name=âarticle-createâ)
</code></pre>

<p>Both these methods require the Passing of the Topic or Section PK to the view or form thru the URL. If there is a better way to do this I am open to other suggestions.  </p>

<p>In Django I have the following Models</p>

<pre><code>class Topic(Audit):
    name = models.CharField(max_length=255)
    sort = models.SmallIntegerField()
    slug = models.SlugField()

    class Meta:
        verbose_name_plural = "topics"

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return ('faq-topic-detail',(), {'slug': self.slug})

class Section(Audit):
    name = models.CharField(max_length=255)
    sort = models.SmallIntegerField()
    slug = models.SlugField()
    topic = models.ForeignKey(Topic,on_delete=models.CASCADE)

    class Meta:
        verbose_name_plural = "sections"

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return ('faq-section-detail',(), {'topic__slug': self.topic.slug,
            'slug': self.slug})

class Article(Audit):
    title = models.CharField(max_length=255)
    sort = models.SmallIntegerField()
    slug = models.SlugField()
    section = models.ForeignKey(Section,on_delete=models.CASCADE)
    answer = models.TextField()
    vote_up = models.IntegerField()
    vote_down = models.IntegerField()
    view_count = models.IntegerField(default=0)

    class Meta:
        verbose_name_plural = "articles"

    def __str__(self):
        return self.title

    def total_votes(self):
        return self.vote_up + self.vote_down

    def percent_yes(self):
        return (float(self.vote_up) / self.total_votes()) * 100

    def get_absolute_url(self):
        return ('faq-article-detail',(), {'topic__slug': self.section.topic.slug,
            'section__slug': self.section.slug, 'slug': self.slug})
</code></pre>

<p>Mysite Forms</p>

<pre><code>class CreateArticleForm(forms.ModelForm):

    class Meta:
        model = Article
        widgets = {
            'answer': forms.Textarea(attrs={'data-provide': 'markdown', 'data-iconlibrary': 'fa'}),
        }
        fields = ('title','section','answer')
</code></pre>

<p>Mysite Views</p>

<pre><code>class TopicCreateView(CreateView):
    model = Topic
    fields = ['name']
    template_name = "faq/form_create.html"
    success_url = "/ironfaq"

    def form_valid(self, form):
        topic = form.save(commit=False)
        activity_user = self.request.user.username
        activity_date = datetime.datetime.now()
        topic.save()
        return super(TopicCreateView,self).form_valid(form)

class SectionCreateView(CreateView):
    model = Section
    fields = ['name', 'topic']
    template_name = "faq/form_create.html"

    def form_valid(self, form):
        section = form.save(commit=False)
        activity_user = self.request.user.username
        activity_date = datetime.datetime.now()
        section.save()
        self.success_url = "/ironfaq/%s/%s" % (section.topic.slug,section.slug)
        return super(SectionCreateView,self).form_valid(form)

class ArticleCreateView(CreateView):
    model = Article
    form_class = CreateArticleForm
    template_name = "faq/form_create.html"

    def form_valid(self, form):
        article = form.save(commit=False)
        activity_user = self.request.user.username
        activity_date = datetime.datetime.now()
        article.save()
        self.success_url = "/ironfaq/%s/%s/%s" % (article.section.topic.slug,article.section.slug,article.slug)
        return super(ArticleCreateView,self).form_valid(form)
</code></pre>

<p>Let's say that you have this url</p>

<pre><code>url(r'^ironfaq/(?P&lt;topic_pk&gt;\d+)/article/create$', ArticleCreateView.as_view(), name=âarticle-createâ)
</code></pre>

<p>Where <code>topic_pk</code> will be pk of topic you want to be associated with your Article. </p>

<p>Then you just need to retrieve it in view. And this is done like this</p>

<pre><code>class ArticleCreateView(CreateView):
    model = Article
    form_class = CreateArticleForm
    template_name = "faq/form_create.html"

    def form_valid(self, form):
        article = form.save(commit=False)
        # what are this variables for?
        activity_user = self.request.user.username
        activity_date = datetime.datetime.now()
        # here we are getting 'topic_pk' from self.kwargs
        article.topic_id = self.kwargs['topic_pk']
        article.save()
        self.success_url = "/ironfaq/%s/%s/%s" % (article.section.topic.slug,article.section.slug,article.slug)
        return super(ArticleCreateView,self).form_valid(form)
</code></pre>

<p>All url params are stored in <code>self.args</code> and <code>self.kwargs</code>. Our <code>topic_pk</code> is named parameter and thats why we can get it by doing <code>self.kwargs['topic_pk']</code></p>

<p>But be sure to validate existence of <code>Topic</code> with such pk before assigning it to your <code>Article</code></p>

python django