I'm using Django allauth as my user account framework for my django site. The docs show there is an ACCOUNT_USERNAME_MIN_LENGTH however there is no ACCOUNT_USERNAME_MAX_LENGTH for some reason.
Is there any way to create a max length for username?
Here's my custom allauth signup form - maybe I can do something here?:
class AllauthSignupForm(forms.Form):
captcha = ReCaptchaField(
public_key=config("RECAPTCHA_PUBLIC_KEY"),
private_key=config("RECAPTCHA_PRIVATE_KEY"),
)
class Meta:
model = User
def signup(self, request, user):
""" Required, or else it throws deprecation warnings """
pass
Edit: Trying to subclass SignupView
draft1/forms.py
class AllauthSignupForm(SignupForm):
def __init__(self, *args, **kwargs):
super(AllauthSignupForm, self).__init__(*args, **kwargs)
self.fields['username']['validators'] += MaxLengthValidator(150,
"Username should be less than 150 character long")
captcha = ReCaptchaField(
public_key=config("RECAPTCHA_PUBLIC_KEY"),
private_key=config("RECAPTCHA_PRIVATE_KEY"),
)
class Meta:
model = User
def signup(self, request, user):
""" Required, or else it throws deprecation warnings """
pass
draft1/views.py
from allauth.account.views import SignupView
class MySignupView(SignupView):
form_class = AllauthSignupForm
allauth/account/urls.py
url(r"^signup/$", MySignupView.as_view(), name="account_signup"),
draft1/settings.py
ACCOUNT_SIGNUP_FORM_CLASS = 'draft1.forms.AllauthSignupForm'
The above code returns this error:
Traceback (most recent call last):
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/utils/autoreload.py", line 228, in wrapper
fn(*args, **kwargs)
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/core/management/commands/runserver.py", line 125, in inner_run
self.check(display_num_errors=True)
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/core/management/base.py", line 359, in check
include_deployment_checks=include_deployment_checks,
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/core/management/base.py", line 346, in _run_checks
return checks.run_checks(**kwargs)
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/core/checks/registry.py", line 81, in run_checks
new_errors = check(app_configs=app_configs)
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/core/checks/urls.py", line 16, in check_url_config
return check_resolver(resolver)
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/core/checks/urls.py", line 26, in check_resolver
return check_method()
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/urls/resolvers.py", line 254, in check
for pattern in self.url_patterns:
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/utils/functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/urls/resolvers.py", line 405, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/utils/functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/urls/resolvers.py", line 398, in urlconf_module
return import_module(self.urlconf_name)
File "/Users/zorgan/Desktop/postr1/lib/python3.5/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 665, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "/Users/zorgan/Desktop/vorsso/venvor/draft1/urls.py", line 6, in <module>
from . import views
File "/Users/zorgan/Desktop/vorsso/venvor/draft1/views.py", line 11, in <module>
from .forms import UserSettingsForm
File "/Users/zorgan/Desktop/vorsso/venvor/draft1/forms.py", line 8, in <module>
from allauth.account.forms import SignupForm
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/allauth/account/forms.py", line 228, in <module>
class BaseSignupForm(_base_signup_form_class()):
File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/allauth/account/forms.py", line 216, in _base_signup_form_class
fc_classname))
django.core.exceptions.ImproperlyConfigured: Module "draft1.forms" does not define a "AllauthSignupForm" class
This can be quickly done by extending DefaultAccountAdapter class and overriding the clean_username method. You need to also reference the clean_username once again after our custom validation to complete other inbuilt validations.
It can be done as follows.
from allauth.account.adapter import DefaultAccountAdapter
from django.forms import ValidationError
class UsernameMaxAdapter(DefaultAccountAdapter):
def clean_username(self, username):
if len(username) > 'Your Max Size':
raise ValidationError('Please enter a username value less than the current one')
return DefaultAccountAdapter.clean_username(self,username) # For other default validations.
Finally, point to the subclass in your settings.py
ACCOUNT_ADAPTER = 'YourProject.adapter.UsernameMaxAdapter'
Reference: https://github.com/pennersr/django-allauth/blob/8fbbf8c1d32832d72de5ed1c7fd77600af57ea6f/allauth/account/adapter.py#L244
You should use a max length validator like below. More documentation about validators here.
from django.core.validators import MaxLengthValidator
from allauth.account.forms import SignupForm
class AllauthSignupForm(SignupForm):
def __init__(self, *args, **kwargs):
self.fields['username']['validators'] += MaxLengthValidator(150, "Username should be less than 150 character long")
Not sure if this is the best way but it works.
After extending the SignupForm, Completely changed the username field with a new one that has the max_length parameter.
from django import forms
from django.utils.translation import ugettext_lazy as _
from allauth.account.forms import SignupForm
class AllauthSignupForm(SignupForm):
username = forms.CharField(label=_("Username"),
min_length=5,
max_length=20, # Change this
widget=forms.TextInput(
attrs={'placeholder':
_('Username'),
'autofocus': 'autofocus'}))
I would like to explain why there is no ACCOUNT_USERNAME_MAX_LENGTH. If you open source code you will see that max_length validator comes from username model field https://github.com/pennersr/django-allauth/blob/330bf899dd77046fd0510221f3c12e69eb2bc64d/allauth/account/forms.py#L277
username_field.max_length = get_username_max_length()
Where get_username_max_length is function that actually pulls max_length value from User model https://github.com/pennersr/django-allauth/blob/8fbbf8c1d32832d72de5ed1c7fd77600af57ea6f/allauth/utils.py#L64
def get_username_max_length():
from .account.app_settings import USER_MODEL_USERNAME_FIELD
if USER_MODEL_USERNAME_FIELD is not None:
User = get_user_model()
max_length = User._meta.get_field(USER_MODEL_USERNAME_FIELD).max_length
else:
max_length = 0
return max_length
First approach: So you could change max_length value directly on your User's model username field if you have it swapped.
I don't think overriding form fields or __init__ method will actually work the it suggested by other answers, because assign of max_length happens in subclass of ACCOUNT_SIGNUP_FORM_CLASS https://github.com/pennersr/django-allauth/blob/330bf899dd77046fd0510221f3c12e69eb2bc64d/allauth/account/forms.py#L259
class BaseSignupForm(_base_signup_form_class()):
where _base_signup_form_class is function that gets your ACCOUNT_SIGNUP_FORM_CLASS
Second approach: is to subclass SignupView and override it's SignupForm read Override signup view django-allauth and How to customize user profile when using django-allauth
In that SignupForm you could actually do what #MehdiB or #PeterSobhi suggested.
ImproperlyConfigured issue occurs because of https://github.com/pennersr/django-allauth/issues/1792
So you be sure that these forms are defined in different python modules as per https://github.com/pennersr/django-allauth/issues/1749#issuecomment-304628013
# base/forms.py
# this is form that your ACCOUNT_SIGNUP_FORM_CLASS is points to
class BaseSignupForm(forms.Form):
captcha = ReCaptchaField(
public_key=config("RECAPTCHA_PUBLIC_KEY"),
private_key=config("RECAPTCHA_PRIVATE_KEY"),
)
class Meta:
model = User
def signup(self, request, user):
""" Required, or else it throws deprecation warnings """
pass
# data1/forms.py
# this is your signup form
from django.core.validators import MaxLengthValidator
from allauth.account.forms import SignupForm
class MySignupForm(SignupForm):
def __init__(self, *args, **kwargs):
super(MySignupForm, self).__init__(*args, **kwargs)
self.fields['username']['validators'] += MaxLengthValidator(150, "Username should be less than 150 character long")
# views.py
from allauth.account.views import SignupView
class MySignupView(SignupView):
form_class = MySignupForm
# urls.py
url(r"^signup/$", MySignupView.as_view(), name="account_signup"),
Try importing with the full name like in your forms :
from allauth.accouts import forms as AllauthForms
class AllauthSignupForm(AllauthForms.SignupForm):
....
i didn't test this and sorry i posted this with my phone i will reformat the answer soon
Related
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.
I am new to django and I started a new project.
shortly, I want to register different type of users (Teacher, Student, Stuff) with their profile picture. I made a one to one field from user to profile and below is my code and I get the following error. if you have any suggestion for my registration purpose, I want to register a different type of user with a profile picture.
models.py
from django.db import models
from django.contrib.auth.models import User,AbstractUser
from django.conf import settings
from django.dispatch import receiver
from django.db.models.signals import post_save
class User(AbstractUser):
USER_TYPE_CHOICES = (
(1,'Student'),
(2,'Teacher'),
(3,'Stuff')
)
profile = models.OneToOneField(on_delete=models.CASCADE, related_name='user')
user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES)
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE, related_name='profile')
photo = models.ImageField(upload_to='users/%Y/%m/%d/')
def __str__(self):
return 'Profile {}'.format(self.user.username)
its the form
from django import forms
from django.contrib.auth.models import User
from .models import Profile
class UserCreationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput, label='Password')
password2 = forms.CharField(widget=forms.PasswordInput, label='Repeat Password')
class Meta:
model = User
fields = ('username', 'first_name', 'last_name')
def clean_password(self):
cd = self.cleaned_data
if cd['password']!=cd['password2']:
raise forms.ValidationError('password no match')
return cd['password2']
class ProfileCreationForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('photo',)
its my view module
from django.shortcuts import render
from .forms import ProfileCreationForm, UserCreationForm
from .models import Profile
from django.http import HttpResponse
def sign_up(request):
if request.method == 'POST':
user_form = UserCreationForm(instance=request.user,data=request.POST)
profile_form = ProfileCreationForm(instance=request.user.profile,data=request.POST,
files=request.FILES)
if user_form.is_valid() and profile_form.is_valid():
new_user = user_form.save(commit=False)
new_user.set_password(user_form.cleaned_data['password'])
new_user.save()
Profile.objects.create(user=new_user)
return HttpResponse('user created')
else:
user_form = UserCreationForm()
profile_form = ProfileCreationForm()
return render(request, '',{'user_form':user_form, 'profile_form':profile_form})
here is the error:
Traceback (most recent call last):
File "manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "C:\Users\Mahdi\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
utility.execute()
File "C:\Users\Mahdi\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\__init__.py", line 357, in execute
django.setup()
File "C:\Users\Mahdi\AppData\Local\Programs\Python\Python37\lib\site-packages\django\__init__.py", line 24, in setup
apps.populate(settings.INSTALLED_APPS)
File "C:\Users\Mahdi\AppData\Local\Programs\Python\Python37\lib\site-packages\django\apps\registry.py", line 112, in populate
app_config.import_models()
File "C:\Users\Mahdi\AppData\Local\Programs\Python\Python37\lib\site-packages\django\apps\config.py", line 198, in import_models
self.models_module = import_module(models_module_name)
File "C:\Users\Mahdi\AppData\Local\Programs\Python\Python37\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "C:\Users\Mahdi\PycharmProjects\MyProject\accounts\models.py", line 7, in <module>
class User(AbstractUser):
File "C:\Users\Mahdi\PycharmProjects\MyProject\accounts\models.py", line 13, in User
profile = models.OneToOneField(on_delete=models.CASCADE, related_name='user')
TypeError: __init__() missing 1 required positional argument: 'to'
In your model you forgot to specify to which model the OneToOneField of the User model should point (a Profile), since that profile is defined later in the Python file, you can not use an identifier, you can however use a string literal that contains the name of the model:
class User(AbstractUser):
USER_TYPE_CHOICES = (
(1,'Student'),
(2,'Teacher'),
(3,'Stuff')
)
profile = models.OneToOneField('Profile', on_delete=models.CASCADE, related_name='user')
user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES)
You will need to make migrations, and migrate in order to add a table that corresponds to your model in the database.
Since you reference to the Profile, that means you will need to first construct a Profile before saving the User (since otherwise the profile will be NULL, which is not allowed here):
from django.shortcuts import render
from .forms import ProfileCreationForm, UserCreationForm
from .models import Profile
from django.http import HttpResponse
def sign_up(request):
if request.method == 'POST':
user_form = UserCreationForm(instance=request.user,data=request.POST)
profile_form = ProfileCreationForm(instance=request.user.profile,data=request.POST,
files=request.FILES)
if user_form.is_valid() and profile_form.is_valid():
profile = profile_form.save()
new_user = user_form.save(commit=False)
new_user.set_password(user_form.cleaned_data['password'])
new_user.profile = profile
new_user.save()
return HttpResponse('user created')
else:
user_form = UserCreationForm()
profile_form = ProfileCreationForm()
return render(request, 'my_template.html',{'user_form':user_form, 'profile_form':profile_form})
You also forgot to specify the template. Furthermore it is advicable to return a redirect(..) to a view, since otherwise if the user refreshes the browser, a second POST request will be made, and this can thus trigger creating another user.
here is an example
you should only create a model with a OneToOne to User
class Profile(models.Model):
usuario = models.OneToOneField(User, on_delete=models.CASCADE,
related_name='profile')
foto = models.ImageField(
upload_to='usuarios/fotos/',
null=True,
blank=True,
)
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")
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.