I am building a chat in django and I have a problem getting objects from the Chat model in django.
For the objects I get a traceback with the message: Manager isn't accessible via Chat instances when I try to access it.
Traceback:
Exception inside application: Manager isn't accessible via Chat instances
File "/Users/fokusiv/Projects/django-multichat-api/venv/lib/python3.6/site-packages/channels/sessions.py", line 179, in __call__
return await self.inner(receive, self.send)
File "/Users/fokusiv/Projects/django-multichat-api/venv/lib/python3.6/site-packages/channels/middleware.py", line 41, in coroutine_call
await inner_instance(receive, send)
File "/Users/fokusiv/Projects/django-multichat-api/venv/lib/python3.6/site-packages/channels/consumer.py", line 59, in __call__
[receive, self.channel_receive], self.dispatch
File "/Users/fokusiv/Projects/django-multichat-api/venv/lib/python3.6/site-packages/channels/utils.py", line 52, in await_many_dispatch
await dispatch(result)
File "/Users/fokusiv/Projects/django-multichat-api/venv/lib/python3.6/site-packages/asgiref/sync.py", line 108, in __call__
return await asyncio.wait_for(future, timeout=None)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/tasks.py", line 339, in wait_for
return (yield from fut)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/concurrent/futures/thread.py", line 56, in run
result = self.fn(*self.args, **self.kwargs)
File "/Users/fokusiv/Projects/django-multichat-api/venv/lib/python3.6/site-packages/channels/db.py", line 13, in thread_handler
return super().thread_handler(loop, *args, **kwargs)
File "/Users/fokusiv/Projects/django-multichat-api/venv/lib/python3.6/site-packages/asgiref/sync.py", line 123, in thread_handler
return self.func(*args, **kwargs)
File "/Users/fokusiv/Projects/django-multichat-api/venv/lib/python3.6/site-packages/channels/consumer.py", line 105, in dispatch
handler(message)
File "/Users/fokusiv/Projects/django-multichat-api/venv/lib/python3.6/site-packages/channels/generic/websocket.py", line 39, in websocket_connect
self.connect()
File "/Users/fokusiv/Projects/django-multichat-api/chat/consumers.py", line 60, in connect
is_participant_in_chat(self.room_name, self.scope['user'])
File "/Users/fokusiv/Projects/django-multichat-api/chat/models.py", line 24, in is_participant_in_chat
test = chat.objects
File "/Users/fokusiv/Projects/django-multichat-api/venv/lib/python3.6/site-packages/django/db/models/manager.py", line 176, in __get__
raise AttributeError("Manager isn't accessible via %s instances" % cls.__name__)
Manager isn't accessible via Chat instances
Here is relevant code:
chat/model.py
from django.shortcuts import get_object_or_404
from django.db import models
import uuid as makeuuid
from users.models import Usern
def is_participant_in_chat(chatid, userid):
chat = get_object_or_404(Chat, uuid=chatid)
test = chat.objects
#Check if userid is in participants
return False
class Chat(models.Model):
uuid = models.UUIDField(primary_key=True, default=makeuuid.uuid4, editable=False)
name = models.CharField(max_length=50, blank=True)
participants = models.ManyToManyField(Usern, related_name='chats')
def __str__(self):
return str(self.uuid)
users/model.py
from django.db import models
import uuid as makeuuid
import os
from django.contrib.auth.models import AbstractUser
class Usern(AbstractUser):
uuid = models.UUIDField(primary_key=True, default=makeuuid.uuid4, editable=False)
name = models.CharField(max_length=50)
def __str__(self):
return str(self.uuid)
Complete project can be found here: https://github.com/martinlundin/django-multichat-api
Appreciate any pointers of how to solve it!
Thanks
Once you have the Chat instance, you can check if the requested user is a participant:
def is_participant_in_chat(chatid, userid):
chat = get_object_or_404(Chat, uuid=chatid)
return chat.participants.filter(uuid=userid).exists()
Just like the error says, you can't access the objects (Manager) from a Chat instance instead you need to use the actual model to access the objects therefore change this line
https://github.com/martinlundin/django-multichat-api/blob/master/chat/models.py#L24 to test = Chat.objects.all() or remove that line since I don't see any use of it currently in the codebase.
Related
I've passed the session object from another class (using Cherrypy cookies) and rebuilt the Nova instance in this class to list the servers. The rebuilt Nova instance works however when I try and create a list of servers, I have an attribute error. There's very little (I found nothing remotely like this issue) out on the internet about this sort of issue.
How do I solve this issue? :)
Code:
import cherrypy
import xmlrpclib
import xml.etree.ElementTree as ET
from keystoneauth1 import loading
from keystoneauth1 import session
import novaclient.client as client
from socket import gethostbyaddr
nova = client.Client("2.1", session=cherrypy.request.cookie.get('sessCookie').value)
serverList = nova.servers.list()
print serverList
Error:
File "/usr/lib/python2.7/site-packages/cherrypy/_cprequest.py", line 656, in respond
response.body = self.handler()
File "/usr/lib/python2.7/site-packages/cherrypy/lib/encoding.py", line 188, in __call__
self.body = self.oldhandler(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/cherrypy/lib/jsontools.py", line 61, in json_handler
value = cherrypy.serving.request._json_inner_handler(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/cherrypy/_cpdispatch.py", line 34, in __call__
return self.callable(*self.args, **self.kwargs)
File "/var/www/frontend/controllers/api/vm.py", line 158, in GET
serverList = nova.servers.list()
File "/usr/lib/python2.7/site-packages/novaclient/v2/servers.py", line 749, in list
"servers")
File "/usr/lib/python2.7/site-packages/novaclient/base.py", line 242, in _list
resp, body = self.api.client.get(url)
File "/usr/lib/python2.7/site-packages/keystoneauth1/adapter.py", line 173, in get
return self.request(url, 'GET', **kwargs)
File "/usr/lib/python2.7/site-packages/novaclient/client.py", line 89, in request
**kwargs)
File "/usr/lib/python2.7/site-packages/keystoneauth1/adapter.py", line 331, in request
resp = super(LegacyJsonAdapter, self).request(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/keystoneauth1/adapter.py", line 98, in request
return self.session.request(url, method, **kwargs)
AttributeError: 'str' object has no attribute 'request'
The value of the session keyword is supposed to be a Keystone session object, but you're passing in a string.
You can read more about working with Keystone sessions here.
I'm working through https://bixly.com/blog/awesome-forms-django-crispy-forms/ , trying to set up a bootstrap 3 form using django crispy forms.
in app1/models.py, I have set up my form:
from django.db import models
from django.contrib.auth.models import User
from django.contrib.auth.models import AbstractUser
from django import forms
class User(AbstractUser):
# Address
contact_name = models.CharField(max_length=50)
contact_address = models.CharField(max_length=50)
contact_email = models.CharField(max_length=50)
contact_phone = models.CharField(max_length=50)
......
Please note I have not created any db tables yet. I don't need them at this stage. I'm just trying to get the forms working. When I run this I get:
Performing system checks...
Unhandled exception in thread started by <function wrapper at 0x02B63EF0>
Traceback (most recent call last):
File "C:\lib\site-packages\django\utils\autoreload.py", line 222, in wrapper
fn(*args, **kwargs)
File "C:\lib\site-packages\django\core\management\commands\runserver.py", line 105, in inner_run
self.validate(display_num_errors=True)
File "C:\lib\site-packages\django\core\management\base.py", line 362, in validate
return self.check(app_configs=app_configs, display_num_errors=display_num_errors)
File "C:\lib\site-packages\django\core\management\base.py", line 371, in check
all_issues = checks.run_checks(app_configs=app_configs, tags=tags)
File "C:\lib\site-packages\django\core\checks\registry.py", line 59, in run_checks
new_errors = check(app_configs=app_configs)
File "C:\lib\site-packages\django\contrib\auth\checks.py", line 12, in check_user_model
cls = apps.get_model(settings.AUTH_USER_MODEL)
File "C:\lib\site-packages\django\apps\registry.py", line 202, in get_model
return self.get_app_config(app_label).get_model(model_name.lower())
File "C:\lib\site-packages\django\apps\config.py", line 166, in get_model
"App '%s' doesn't have a '%s' model." % (self.label, model_name))
LookupError: App 'app1' doesn't have a 'models' model.
How can I fix this?
The AUTH_USER_MODEL settings should be of the form <app name>.<model>. Your model name is User, not model, so your setting should be:
AUTH_USER_MODEL = 'app1.User'
You should also remove the following User import from your models.py. You only have to import AbstractUser.
from django.contrib.auth.models import User
I am trying to build a view where forms are loaded dynamically based on the form slug, the available forms are defined in a list of tuples like this, this is meant to speed up development of new forms in a "framework-like" way:
#installed_io.py
forms = [("json",JsonForm),("csv",CsvForm),....]
froms are defined in the forms.py module as usual.
from django import forms
class FileForm(BaseDatasetForm):
file = forms.FileField(label="Opcion 1: Seleccione un archivo", required=False)
text = forms.CharField(widget=forms.Textarea, label="Opction 2: Introduzca el contenido en este campo", required=False)
utils.py defines the function to dynamically select the Form class:
from installed_io import installed_inputs
def get_input_form(slug):
for entry in installed_inputs:
if entry[0] == slug:
return entry[1]
raise NotImplementedError("The required form is not implemented or missing from the installed inputs")
The view is defined in the views.py module of my django app:
#views.py
from utils import get_input_form
#login_required
def add(request, slug):
InputForm = get_input_form(slug)
if request.method == "POST":
form = InputForm(request.POST, request.FILES)
if form.is_valid():
object_id = form.save()
messages.success(request, "Dataset created")
return redirect(reverse("input:dataset", args=[str(object_id.inserted_id)]))
else:
form = InputForm()
return render(request, "datasets/add-form.html", {"form":form})
but I'm getting this import error:
python manage.py runserver
Unhandled exception in thread started by <function wrapper at 0x7fe9c465c398>
Traceback (most recent call last):
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 109, in inner_run
autoreload.raise_last_exception()
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 249, in raise_last_exception
six.reraise(*_exception)
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/__init__.py", line 18, in setup
apps.populate(settings.INSTALLED_APPS)
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/apps/registry.py", line 108, in populate
app_config.import_models(all_models)
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/apps/config.py", line 202, in import_models
self.models_module = import_module(models_module_name)
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
File "/home/jesus/workspace/tensorflow-board-django/tensorflow_board_django/analysis/models.py", line 2, in <module>
from ..input.forms import SOURCES
File "/home/jesus/workspace/tensorflow-board-django/tensorflow_board_django/input/forms.py", line 2, in <module>
from utils import save_dataset
File "/home/jesus/workspace/tensorflow-board-django/tensorflow_board_django/input/utils.py", line 2, in <module>
from installed_io import installed_inputs
File "/home/jesus/workspace/tensorflow-board-django/tensorflow_board_django/input/installed_io.py", line 1, in <module>
from forms import FileForm
ImportError: cannot import name FileForm
What I've tried:
Changing the import statements using absolute paths
Deleting pyc files
Using dot notation to import modules
Trying to save the installed_input list on init.py
Only moving all the code to the views.py file worked, but I find this solution to be very monolithic and non-pythonic.
Based on the comments on the original post I made the following changes to my code:
instead of importing classes on installed_io module I used strings:
#installed_io.py
forms = [("json","JsonForm"),("csv","CsvForm"),....]
then I changed utils.py to import the class from string:
from installed_io import installed_inputs
def get_input_form(slug):
for entry in installed_inputs:
if entry[0] == slug:
module = importlib.import_module("tensorflow_board_django.io.forms")
class_name = entry[1]
return getattr(module, class_name)
raise NotImplementedError("The required form is not implemented or missing from the installed inputs")
views.py
def add_post(topic, request):
post_form = PostForm(request.POST)
if 'submit' in request.POST and post_form.validate():
post = Post(body=post_form.body.data)
post.user = request.user
post.topic = topic
DBSession.add(post)
request.session.flash(_('Post was added'))
transaction.commit()
raise HTTPFound(location=request.route_url('topic',id=topic.id))
return {'post_form':post_form}
models.py
class Topic(Base):
__tablename__ = 'topics'
id = Column(Integer, primary_key=True)
...
post_count = Column(Integer, default=0)
posts = relationship('Post', primaryjoin="Post.topic_id==Topic.id", backref='topic', lazy='dynamic')
class Post(Base):
__tablename__ = 'posts'
id = Column(Integer, primary_key=True)
...
topic_id = Column(Integer, ForeignKey('topics.id'))
def post_inserted(mapper, conn, post):
topic = post.topic
topic.post_count = topic.posts.count()
event.listen(Post, "after_insert", post_inserted)
I want in my Pyramid app to use SQLAchemy event 'after_insert', to update Topic model with number of posts belong to it. But I get exeption:
Traceback (most recent call last):
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/waitress/channel.py", line 329, in service
task.service()
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/waitress/task.py", line 173, in service
self.execute()
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/waitress/task.py", line 380, in execute
app_iter = self.channel.server.application(env, start_response)
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/pyramid/router.py", line 251, in __call__
response = self.invoke_subrequest(request, use_tweens=True)
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/pyramid/router.py", line 227, in invoke_subrequest
response = handle_request(request)
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/pyramid_tm/__init__.py", line 107, in tm_tween
return response
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/transaction/_manager.py", line 116, in __exit__
self.commit()
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/transaction/_manager.py", line 107, in commit
return self.get().commit()
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/transaction/_transaction.py", line 354, in commit
reraise(t, v, tb)
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/transaction/_transaction.py", line 345, in commit
self._commitResources()
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/transaction/_transaction.py", line 493, in _commitResources
reraise(t, v, tb)
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/transaction/_transaction.py", line 465, in _commitResources
rm.tpc_begin(self)
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/zope/sqlalchemy/datamanager.py", line 86, in tpc_begin
self.session.flush()
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/sqlalchemy/orm/session.py", line 1583, in flush
self._flush(objects)
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/sqlalchemy/orm/session.py", line 1654, in _flush
flush_context.execute()
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/sqlalchemy/orm/unitofwork.py", line 331, in execute
rec.execute(self)
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/sqlalchemy/orm/unitofwork.py", line 475, in execute
uow
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/sqlalchemy/orm/persistence.py", line 67, in save_obj
states_to_insert, states_to_update)
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/sqlalchemy/orm/persistence.py", line 702, in _finalize_insert_update_commands
mapper.dispatch.after_insert(mapper, connection, state)
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/sqlalchemy/event.py", line 291, in __call__
fn(*args, **kw)
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/sqlalchemy/orm/events.py", line 360, in wrap
wrapped_fn(*arg, **kw)
File "/home/user/workspace/myforum/cube_forum/models.py", line 165, in post_saved
topic.post_count = topic.posts.count()
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/sqlalchemy/orm/dynamic.py", line 249, in count
sess = self.__session()
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/sqlalchemy/orm/dynamic.py", line 219, in __session
sess.flush()
File "/home/user/workspace/myforum/env/lib/python2.6/site-packages/sqlalchemy/orm/session.py", line 1577, in flush
raise sa_exc.InvalidRequestError("Session is already flushing")
InvalidRequestError: Session is already flushing
How to do it right in Pyramid/SQLalchemy?
EDIT: Question is actually how to use SQLAlchemy's events in Pyramid.
SQLAlchemy event "after_insert" not suitable for this task.
The answer is using Pyramid's custom events as described here http://dannynavarro.net/2011/06/12/using-custom-events-in-pyramid/
I see that there is a problem on the database level - there no guarantee to get valid posts count value. Imagine if two or more posts were added to topic at the same time within multiple transactions - there is no way to tell for sure valid count of associated posts unless you will lock topic table or record every time you are adding new post.
Possible solutions:
1) Add method to Topic class. Always valid number, but it will execute query into db every time.
class Topic(Base):
...
def posts_count(self):
return self.posts.count()
2) Add post to topic and update post_count in your code without using after_insert event. You'll need to update topic.post_count every time when you change topic for post. Also this method won't resolve issue I described when several posts were added to topic at the same time.
def add_post(topic, request):
post_form = PostForm(request.POST)
if 'submit' in request.POST and post_form.validate():
post = Post(body=post_form.body.data)
post.user = request.user
topic.posts.append(post)
topic.post_count = topic.posts.count()
DBSession.add(post)
DBSession.add(topic)
request.session.flash(_('Post was added'))
transaction.commit()
raise HTTPFound(location=request.route_url('topic',id=topic.id))
return {'post_form':post_form}
I've model which represents settings in my system and I use it from another part of my application so that import has 3 levels WORKING CODE <- Module <- Model
Model Variables
from django.db import models
class Variables(models.Model):
key = models.CharField(max_length = 20, verbose_name = 'Variable')
value = models.CharField(max_length = 1024)
class Meta:
app_label = 'core'
def __unicode__(self):
return '%s: %s' % (self.key, self.value,)
Here is the code I'm using it from
Module variables.py
from core.models.storage import Variables
def get_var(name):
return Variables.objects.get(key = name)
Module config.py
var = get_var('some_key')
When I use this stuff from django shell everything works well but when I call get_var function I've ImportError exception
storage.py
from django.db import models
class Variables(models.Model):
key = models.CharField(max_length = 20, verbose_name = 'Variable')
value = models.CharField(max_length = 1024)
class Meta:
app_label = 'core'
def __unicode__(self):
return '%s: %s' % (self.key, self.value,)
File "monitor_cli.py", line 19, in
print worker.get_provider()
File "/home/sultan/Project/monitor/app/worker.py", line 14, in get_provider
print Variables.objects.get(pk=1)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/manager.py", line 132, in get
return self.get_query_set().get(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 341, in get
clone = self.filter(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 550, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 568, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py", line 1172, in add_q
can_reuse=used_aliases, force_having=force_having)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py", line 1060, in add_filter
negate=negate, process_extras=process_extras)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py", line 1226, in setup_joins
field, model, direct, m2m = opts.get_field_by_name(name)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/options.py", line 307, in get_field_by_name
cache = self.init_name_map()
File "/usr/local/lib/python2.6/dist-packages/django/db/models/options.py", line 337, in init_name_map
for f, model in self.get_all_related_m2m_objects_with_model():
File "/usr/local/lib/python2.6/dist-packages/django/db/models/options.py", line 414, in get_all_related_m2m_objects_with_model
cache = self._fill_related_many_to_many_cache()
File "/usr/local/lib/python2.6/dist-packages/django/db/models/options.py", line 428, in _fill_related_many_to_many_cache
for klass in get_models():
File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 167, in get_models
self._populate()
File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 61, in _populate
self.load_app(app_name, True)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 76, in load_app
app_module = import_module(app_name)
File "/usr/local/lib/python2.6/dist-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
ImportError: No module named c
Get rid of the models directory, and put all your models in a models.py file, unless you have a VERY good reason not to. Change your imports to from core.models import Variable (rename your Variables class to Variable - django models should be named as the singular not the plural).
The problem probably has to do with the fact that your models live in namespaces other than models; ie. models.storage. The django infrastructure expects certain things to be in certain places. If you're going to put models in separate namespaces like you're doing, you should be importing them from the __init__.py file within the models module. Don't do this, again, unless you have a very good reason.
Finally, when asking questions of this nature, you should provide a lot more information. You should show the code of all of the relevant files. You should provide detail on what you've done that deviates from the convention of django (in this case, a models directory rather than a models.py file). You should also show relevant settings from settings.py, in this case, your INSTALLED_APPS setting. You should also tell us what version of django and python you are using; this is sometimes relevant. More information upfront is much better than less information.