Search code examples
pythondjangovariablesurlenvironment

How to use url variables in class based views


I'm having problems with the url variables and the class based views, but mostly in the html or template because I don't know how to represent it, I'll show you the code so you can understand.

urls.py

app_name = 'app1'

urlpatterns = [
    path('add_post/<str:sym>',AddPostView.as_view(), name='addpost'),
]

views.py

class AddPostView(CreateView):
    model = Post
    form_class = PostForm
    template_name = 'app1/createpost.html'

    def get_queryset(self):
        ala = Post.objects.filter(stock__symbol=self.kwargs['sym'])
        return ala

models.py

class StockNames(models.Model):
    name = models.CharField(max_length=255)
    symbol = models.CharField(max_length=255)

    def __str__(self):
        return self.symbol

        
    

class Post(models.Model):
    title = models.CharField(max_length= 255)
    header_image = models.ImageField(null = True, blank = True, upload_to = 'images/')
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    body = RichTextField(blank = True, null = True)
    #body = models.TextField()
    post_date = models.DateField(auto_now_add=True)
    category = models.CharField(max_length=255, default='coding')
    snippet = models.CharField(max_length=255)
    likes = models.ManyToManyField(User, related_name = 'blog_posts')
    stock = models.ForeignKey(StockNames, null=True, on_delete = models.CASCADE)

    def total_likes(self):
        return self.likes.count()

    def __str__(self):
        return self.title + ' | ' + str(self.author)
    
    def get_absolute_url(self):
        return reverse('app1:article-detail', args=(self.id,))

Template (I'm having problems with Add Post(current) )

{% extends "app1/base.html" %}
    {% block body_block %}
    
    
    {% if stock_sym %}
    <h1> {{sym}} </h1>
    <a href ="{% url 'app1:addpost' StockNames.symbol %}">Add Post<span class="sr-only">(current)</span></a> 
        {% if stocks %}
    
        
        <ul>
        {% for post in stocks %}
        <li><a href="{% url 'app1:article-detail' post.pk %}">{{sym}}</a> -
            {{post.author}} - <small>{{post.post_date}}</small> - 
            {% if user.is_authenticated %}
            <small><a href="{% url 'app1:updatepost' post.pk %}">Edit</a></small><small>
            <a href="{% url 'app1:deletepost' post.pk %}">- Delete</a>  
            </small></li>
            {% endif %}
            {{post.body|slice:":200"|safe}} 
    
        {% endfor %}
        </ul>
    {% else %}
    <h1>No posts yet</h1>
    {% endif %}
    {% else %}
    <h1>hey</h1>
    {% endif %}
    {% endblock %}

trace

Traceback (most recent call last):
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\core\handlers\base.py", line 202, in _get_response
    response = response.render()
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\response.py", line 105, in render
    self.content = self.rendered_content
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\response.py", line 83, in rendered_content
    return template.render(context, self._request)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\backends\django.py", line 61, in render
    return self.template.render(context)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\base.py", line 170, in render
    return self._render(context)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\base.py", line 162, in _render
    return self.nodelist.render(context)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\base.py", line 938, in render
    bit = node.render_annotated(context)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\base.py", line 905, in render_annotated
    return self.render(context)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\base.py", line 162, in _render
    return self.nodelist.render(context)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\base.py", line 938, in render
    bit = node.render_annotated(context)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\base.py", line 905, in render_annotated
    return self.render(context)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\defaulttags.py", line 312, in render
    return nodelist.render(context)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\base.py", line 938, in render
    bit = node.render_annotated(context)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\base.py", line 905, in render_annotated
    return self.render(context)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\template\defaulttags.s.py", line 446, in render
    url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\urls\base.py", line 8 87, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "C:\Users\snin2\anaconda3\envs\MyDjangoEnv\lib\site-packages\django\urls\resolvers.py", l line 685, in _reverse_with_prefix
    raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'addpost' with no arguments not found. 1 pattttern(s) tried: ['app1/add_post/(?P<sym>[^/]+)$']

Thanks in advance! So the main problem is putting the link in the href of the template, I don't know how to express it.


Solution

  • **EDIT

    Try:

    <a href ="{% url 'app1:addpost' sym=sym %}">Add Post<span class="sr-only">(current)</span></a>
    

    Views.py - try switching your method for get_context_data:

    class AddPostView(CreateView):
        model = Post
        form_class = PostForm
        template_name = 'app1/createpost.html'
    
        def get_context_data(self, *args, **kwargs):
            context = super().get_context_data(**kwargs)
            context.update(
                sym=get_object_or_404(StockNames, StockNames.symbol)
            )
            return context
    

    Here is a link to the appropriate Django documentation for more info:

    https://docs.djangoproject.com/en/3.1/topics/class-based-views/generic-display/#adding-extra-context