0

I am trying to access the object used in Django DetailView and used to display Model data.

I can access the object in the html template, by {{ object.product_name }}.

But, how do I access the object in a function, like below? (within views.py).

def access_object_values(self):
      name = object.product_name   

(my attempts fail and I get: WSGIRequest' object has no attribute)

. .

My setup:

*models.py*

    class Product(models.Model):
          product_name = models.Charfield(max_length=20)
          product_price = models.FloatField(max_length=12, default=100)

*urls.py*

    path('product/<int:pk>/', ProductView.as_view(), name='product-detail)

My attempts:

class ProductView(DetailView):
    model = Product
    template_name = 'product/product_detail.html'

    def get_object(self, queryset=None):
        if queryset is None:
            queryset = self.get_queryset()
        obj = super(ProductView, self).get_object(queryset=queryset)
        return obj

    def get(self, obj, *args, **kwargs):
        return self.generate_pdf(obj)


    # TO VISUALLY GET FEEDBACK OF SUCCESS OR NOT
    # ==========================================
    def generate_pdf(self, obj):
        from reportlab.pdfgen import canvas
        response = HttpResponse(content_type='application/pdf')
        response['pdf'] = 'attachment; filename="summary.pdf"'
        p = canvas.Canvas(response)
        # name = getattr(obj, 'product_name') # produces 'WSGIRequest' object has no attribute 'product_name'
        # name = obj.product_name             # produces 'WSGIRequest' object has no attribute 'product_name'
        # name = type(obj)                    # produces 'WSGIRequest' has no attribute 'decode
        name = "text"                         # this works, and it prints
        p.drawString(100, 100, name)
        p.showPage()
        p.save()
        print(p)
        return response
Jaco
  • 1,564
  • 2
  • 9
  • 33
  • What your trying to achieve could you please me more clear. If you need anything in pageload you can try to override get_contextdata method and add a response – Midhun Mohan Dec 18 '18 at 05:25
  • hi Midhun, I re-wrote it a bit given your question: "" Instead of having a primary interest to display the data in a template, such as {{ object.product_name }}, the focus here is to access the data values within the object, to be used in another sub-routine, e.g. to print a document or to calculate a value: "" , ie how to access the object detailview is using for the template instead of writing another / new database request to question the object again – Jaco Dec 18 '18 at 05:34
  • try this in your get object method obj = super().get_object(queryset=self.model.objects.get(pk=self.kwargs.get("pk"))) @jaco i would be more clear since it is a detail view – Midhun Mohan Dec 18 '18 at 05:53
  • got an error 'Product' object has no attribute 'filter',, I thought the version I had would get to the specific object directly, without using filter,, but seems not to work ,, obj = super(ProductView, self).get_object(queryset=queryset) – Jaco Dec 18 '18 at 06:09
  • intially you are setting queryset to none and trying to fetch a none queryset that will cause to return a none object – Midhun Mohan Dec 18 '18 at 06:19
  • 1
    found like you need to use this if queryset is None: queryset = self.get_queryset() – Midhun Mohan Dec 18 '18 at 06:21
  • great, thxs, I am trying to run a test to see if it works, but cannot get any values to the pdf, do you have another suggestion how to test if it pulls the data or the object is emtpy? – Jaco Dec 19 '18 at 19:27

3 Answers3

1

A method get_object should return an object. Try:

def get_object(self, queryset=None):
    obj = super(ProductView, self).get_object(queryset=queryset)
    self.generate_pdf(obj)
    return obj

def generate_pdf(self, obj):
    from reportlab.pdfgen import canvas
    p = canvas.Canvas(response)
    name = obj.product_name
    p.drawString(100, 100, name )
    p.showPage()
    p.save()
    print(p)

If you want just to print it, no need for response here.

Sergey Pugach
  • 5,561
  • 1
  • 16
  • 31
1
def get_object(self, queryset=None):
   if queryset is None:
       queryset = self.get_queryset()
   obj = super(ProductView, self).get_object(queryset=queryset)
    self.generate_pdf(obj)
    return obj

def generate_pdf(self, obj):
    from reportlab.pdfgen import canvas
    p = canvas.Canvas(response)
    name = obj.product_name
    p.drawString(100, 100, name )
    p.showPage()
    p.save()
    print(p)

This could be what you are looking for

Midhun Mohan
  • 552
  • 5
  • 18
  • Thanks, I have tried it out, it took me ahead, but not the whole way, as I cannot question the object,, see my amended question for implementation of your help. – Jaco Dec 18 '18 at 14:07
0

A useful answer, if one wants to access context and use it as variables: Accessing global variable in view using context processor in Django

Add your context processor method path (folder.context_processor.application_context) to TEMPLATE_CONTEXT_PROCESSORS.

in my case application_context is the method which i defined inside file context_processor.py and method "application_context" returns {'titles': 'mytitle'}

if you want to use "title" as global variable in views use it in this way

global_var = RequestContext(request).get("app_config")
titles = global_var.get("titles")
print titles

Another useful answer is here: Django: How to provide context to all views (not templates)?

Jaco
  • 1,564
  • 2
  • 9
  • 33