ERROR MSG:
The web page throws another view when I am trying to create another view and see the contents I have saved in the DB.
In models.py:
from django.db import models
# Create your models here.
class pichuur(models.Model):
def __str__(self):
return self.name + '-' + self.language
name=models.CharField(max_length=100)
language= models.CharField(max_length=100)
Genre= models.CharField(max_length=100)
Year= models.CharField
Category= models.CharField(max_length=100)
Cast= models.CharField(max_length=500)`
from django.shortcuts import render
in views.py:
# Create your views here.
from django.http import HttpResponse
from .models import pichuur
def index(request):
Sab_movies = pichuur.objects.all()
html=''
for pichuur in Sab_movies:
url= '/Movies/' + str(pichuur.id) + '/'
html+= '' + '<br>'
return HttpResponse("<h> Welcome to Movies </h>")
def detail(request, pichuur_id):
return HttpResponse("<h2> Details for Movie Id:" + str(pichuur_id) + "</h2>")
You are using pichuur as a local variable in the for loop:
for pichuur in Sab_movies:
This means Python expects to be able to assign to it, and before the for loop starts, the name is unbound, has no value assigned to it.
That that name is also the name of your model doesn't matter any more. So the statement Sab_movies = pichuur.objects.all() fails, because pichuur is not yet set by the for loop.
The solution is to use a different names for your model and the loop target variable. Don't reuse model names as local variable names. And in the Python style guide, classes (such as Django models) should use CamelCase names, precisely to avoid mistakes like these.
So here specifically, I'd rename the model to use an uppercase P:
class Pichuur(models.Model):
then in views.py use that new name:
from .models import Pichuur
and
Sab_movies = Pichuur.objects.all()
Related
I need to make a dynamic path for a file that I want to open. I need to retrieve the .tif file from within a path.
this path is formed by a combination of a "STATICFILES_DIRS" from my settings.py and a field ccalled docId from my models.py that get filled from the views.py
now, I'm very new to django so I really don't understand what I dont know (if this makes sense)
my views.py has the following:
from django.shortcuts import render
import pyodbc
# Create your views here.
def home(request): conn=pyodbc.connect('Driver={sql server};'
'Server=server.domain.com;' 'Database=database;' 'Trusted_Connection=yes;')
cursor = conn.cursor() cursor.execute("select top 100 docId, supplierName,
invoiceNumber, reference from table") result = cursor.fetchall() return
render(request, 'azolve/home.html', {'Azolve': result})
and my models.py has this:
from django.db import models
import os import fnmatch
class Azolve(models.Model):
docId = models.IntegerField
supplierName = models.CharField(max_length=100)
invoiceNumber = models.IntegerField
reference = models.CharField(max_length=100)
# for file_name in os.listdir(str(filePath)):
# if fnmatch.fnmatch(file_name, '*.tif'):
# docIdFileName = file_name
and in my settings.py I have this part:
STATIC_URL = '/static/'
STATICFILES_DIRS = [ "//server1/Shared1/folder/ Migration Images/", ]
so, to give an idea, each docId that gets retrieved is the name of a folder contained in the path "STATICFILES_DIRS " what I was trying to do is to navigate for each folder and get the .tif file inside the folder, so I can concatenate and make the complete filename with the format:
//server1/Shared1/folder/ Migration Images/--docIDFOLDER--/FILENAME.TIF
this would later be shown in a table in my html file doing something like:
<tbody>
{% for datarow in Azolve %}
<tr>
<td>{{datarow.supplierName}}</td>
<td>{{datarow.invoiceNumber}}</td>
<td>{{datarow.reference}}</td> <td><a href= ' {% static "" %}{{ datarow.docId }}/{{ datarow.docIdFileName }}'>Open Invoice</a></td> </tr>
{% endfor %}
</tbody>
Does this makes sense? I've been checking different django tutorials, but I couldn't find an example of something similar to what I need to do :(
I don't know how should I get this data so I can concatenate and then pass it to the "datarow"
I've tried adding this in the models but I think is not correct to add it on the class, should be then in the views inside the function? as a new function?
Note: I'm not having the user upload files, these are stored in a network drive and I only need to have users look for them and download them, my problem is generating the complete path from the folder where the .tif file is stored (I get to "//Server/Folder/Folder2/docIdFolder/XXXX.tif" but I can't assign the value of the XXXX.tif part.
I would suggest adding a field to the model to store the file name, and look it up once from the file system, storing it in the db after that.
class Azolve(models.Model):
docId = models.IntegerField
supplierName = models.CharField(max_length=100)
invoiceNumber = models.IntegerField
reference = models.CharField(max_length=100)
img_filename = models.CharField(max_length=255, blank=True, null=True)
but also add a def to the Azolve model class which attempts to populate that img_filename if it doesn't exist. Something along the lines of the following which tries to locate the .tif using pathlib's glob (https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob):
# put this at the top of your models.py
from pathlib import Path
# and this right in your class
def tif_file(self):
if self.img_filename:
return self.img_filename:
else:
search_path = Path(r'//server1/Shared1/folder/Migration Images')
# the filter likely not needed, was using this in where I copied from
files_in_path = list(filter(Path.is_file, search_path.glob('*.tif')))
if files_in_path:
# may have to wrap the files_in_path with str()
# untested, writing in the s/o answer box
self.img_filename = files_in_path[0]
return files_in_path[0]
else:
return None
Then in your template you should be able to use {{datarow.tif_file}}. From a performance standpoint, I'm not certain if this would get run everytime you reference this record or not or if it would only fire when called upon. Might be worth tracing through the debugger.
from django.contrib import admin
from .models import Shop
#admin.register(Shop)
class ShopAdmin(admin.ModelAdmin):
#admin.display(description='Name')
def upper_case_name(self,obj):
return("%s" % (obj.name)).upper()
Using the answer from Jermaine, you can create your own decorator and monkey patch it to the admin module. This would allow you to use the #admin.display(description="...") decorator.
# Monkey patch admin to include the display decorator (available in future Django versions)
if not hasattr(admin, "display"):
def display(description):
def decorator(fn):
fn.short_description = description
return fn
return decorator
setattr(admin, "display", display)
Complete example:
from django.contrib import admin
from .models import Shop
# Monkey patch admin to include the display decorator (available in future Django versions)
if not hasattr(admin, "display"):
def display(description):
def decorator(fn):
fn.short_description = description
return fn
return decorator
setattr(admin, "display", display)
#admin.register(Shop)
class ShopAdmin(admin.ModelAdmin):
#admin.display(description='Name')
def upper_case_name(self,obj):
return("%s" % (obj.name)).upper()
This is not a super clean approach, but if you would like to use the decorator you can do it this way.
In my case you should activate virtualenv , by typing "pipenv shell" command
I think it helps you too
In my case, for some reason, django was downgraded. I ran "pipenv update django" and it worked.
You can still achieve the same goal without using the display decorator.
list_display = ('upper_case_name',)
def upper_case_name(self, obj):
return "%s" % (obj.name.upper())
upper_case_name.short_description = "Name"
Django==3.1
I was fighting with this for a while, I didn't understand why the #admin.action() decorator didn't appear, I started to read the Django code and I found that when the actions for the Django Admin start to load, it calls a method called _get_base_actions, and this same method gets the action and description in this way:
# django.contrib.admin.ModelAdmin._get_base_actions
...
description = getattr(func, 'short_description', name.replace('_', ' '))
...
I had already tried several ways to load the action and to correctly take the description of the action, if it was not defined, what Django did was to take the name of the same function and replace the underscores with spaces, resulting in a somewhat frightening result.
The first thing I thought of as a quick and valid solution was to create a class and modify the __new__ method, which is called before the __init__ method.
This is an example of what I needed, to be able to generate a PDF from Django actions:
class GeneratePDF:
short_description = "WRITE THE DESCRIPTION OF ACTION HERE"
def __new__(cls, modeladmin, request, queryset):
result = cls.generate_pdf_resume(modeladmin, request, queryset)
return result
#classmethod
def generate_pdf_resume(cls, modeladmin, request, queryset):
...
Finally, I added it to the list of ModelAdmin actions.
from project.own_actions import GeneratePDF
#admin.register(Patient)
class PatientAdmin(admin.ModelAdmin):
...
actions = [GeneratePDF]
Then it appeared with the description that I had placed in the class as a class attribute.
I could also reuse this class to create a URL and successfully generate the PDF.
# project/urls.py
from project.own_actions import GeneratePDF
urlpatterns = [
path('admin/', admin.site.urls),
...
path('export/', GeneratePDF, name="export-pdf")
]
I have model
Order(models.Model):
name = models.Charfield()
#classmethod
do_something(cls):
print('do soemthing')
What I want to do is to move do_something method from my model to another file.I want to do it because I have several other big methods in this model and want to structure the code, don't like lengh of this file. It's getting big > 700 lines of code.
So I want to move my method to another file and import it, so it still can be used like modelmethod
like this:
Order.do_something()
Any ideas?
Use inheritance -- (wiki)
# some_package/some_module.py
class MyFooKlass:
#classmethod
def do_something(cls):
# do something
return 'foo'
# my_app/models.py
from some_package.some_module import MyFooKlass
class Order(models.Model, MyFooKlass):
name = models.CharField()
I'm trying to learn how to create python-based back-ends from some existing data that i have collected. I've come to realize that i definitely want to use sqlalchemy and that flask seems like a good library to go with it. My problem is that even after many hours of reading the sqlalchemy docs and browsing various answers on stackexchange i still don't understand how i can reshape data from an existing table into an object with a completely different structure.
The transformation i want to do is very concrete. I want to go from this structure in my MariaDB table:
Columns: company_name, date, indicators(1...23)
To this json output generated from a serialized class object:
{
"company_name[1]":
{
"indicator_name[1]":
{
"date[1]": "indicator_name[1].value[1]",
"date[2]": "indicator_name[1].value[2]",
"date[3]": "indicator_name[1].value[3]",
"date[4]": "indicator_name[1].value[4]",
"date[5]": "indicator_name[1].value[5]"
},
"indicator_name[2]":
{
"date[1]": "indicator_name[2].value[1]",
"date[2]": "indicator_name[2].value[2]",
"date[3]": "indicator_name[2].value[3]",
"date[4]": "indicator_name[2].value[4]",
"date[5]": "indicator_name[2].value[5]"
},
I found a great tutorial with which i can output the entire table record by record but the structure is not what i want, and i don't think creating the desired structure on the front-end makes sense in this case.
Here is the code that outputs the entire table to json record by record:
from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import PrimaryKeyConstraint
from sqlalchemy import orm
from sqlalchemy import select, func
from sqlalchemy import Column, Integer, String, ForeignKey
from flask_marshmallow import Marshmallow
import decimal
import flask.json
class MyJSONEncoder(flask.json.JSONEncoder): # Enables decimal queries for the API
def default(self, obj):
if isinstance(obj, decimal.Decimal):
# Convert decimal instances to strings.
return str(obj)
return super(MyJSONEncoder, self).default(obj)
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://USER:PASS#localhost:3306/kl_balance_sheets'
app.json_encoder = MyJSONEncoder
db = SQLAlchemy(app)
ma = Marshmallow(app)
# Bind declarative base to engine
db.Model.metadata.reflect(db.engine)
class CompanyData(db.Model):
__table__ = db.Model.metadata.tables['kl_balance_sheets']
class CompanyDataSchema(ma.ModelSchema):
class Meta:
model = CompanyData
#app.route('/')
def index():
company_data = CompanyData.query.all()
company_data_schema = CompanyDataSchema(many=True)
output = company_data_schema.dump(company_data).data
return jsonify({'company_data' : output})
if __name__ == '__main__':
app.run(debug=True)
My main question i guess is: How do i edit this code to produce the desired json?
What i think i should do is to create a custom constructor and then feed that into the index function but i can't figure out how to concretely do that. The two options i've come across are:
#orm.reconstructor
def init_on_load(self):
#do custom stuff
or:
class Foo(db.Model):
# ...
def __init__(**kwargs):
super(Foo, self).__init__(**kwargs)
# do custom stuff
To me this seems like a basic operation any flask-marshmallow user would be doing regularly. Could someone please explain how sql data is normally inserted into an object with a new structure and then serialized? In my case, do i need to change things mainly on the metadata, object or marshmallow level? I'm surprised i can't find some good examples of this.
I followed the installation instructions on django-user-accounts.
When calling http://[mysite]/account/signup
I could see:{# This template intentionally left blank to satisfy test suites. Your project should always provide a site_base.html itself. #} (and I take it as a good sign, I'll add my base template later).
After that, i created an app: ./manage.py startapp myapp_account
...and filled it with the minimum code from the "Usage" page of the manual mentioned above as i want to get a basic working register/login/out.
Now i get an error when calling http://[mysite]/account/signup/:
Exception Value: 'module' object has no attribute 'views'
Exception Location: /var/www/venv/django_1/django_1/urls.py in <module>, line 10
Python Executable: /var/www/venv/bin/python3.4
my code:
urls.py (main project called django_1):
from django.conf.urls import patterns, include, url
import myapp_account
urlpatterns = patterns('',
# this is line 10 in my case:
url(r'^account/signup/$', myapp_account.views.SignupView(),name="account_signup"),
url(r'^account/', include('account.urls')),
)
myapp_account/views.py:
import account.views
import account.forms
import myapp_account.forms
class SignupView(account.views.SignupView):
form_class = myapp_account.forms.SignupForm
def after_signup(self, form):
self.create_profile(form)
super(SignupView, self).after_signup(form)
def create_profile(self, form):
profile = self.created_user.get_profile()
profile.birthdate = form.cleaned_data["birthdate"]
profile.save()
class LoginView(account.views.LoginView):
form_class = account.forms.LoginEmailForm
myapp_account/forms.py
from django import forms
from django.forms.extras.widgets import SelectDateWidget
import account.forms
class SignupForm(account.forms.SignupForm):
birthdate = forms.DateField(widget=SelectDateWidget(years=range(1930, 2010)))
Is there a simpler way do get it working and be on the right track to extend the user accounts step by step?
As usual the answer was in the manual Django, Class-based views
:
Import the class based view directly
Call the class based view directly in the url
updated urls.py (main)
from django.conf.urls import patterns, include, url
from myapp_account.views import SignupView # <- import class based view
urlpatterns = patterns('',
# call class based view directly:
url(r'^account/signup/$', SignupView.as_view(), name="account_signup"),
url(r'^account/', include('account.urls')),
)
Still i'd be happy if someone cloud point me to a well made example of django-user-accounts.