2016-12-25 66 views
4

我在我的兩個文件中有圓形問題。在創建對象時運行模型導入函數,並在此函數中導入模型以檢查代碼是否唯一。Django ImportError:無法導入名稱'x'

如何在模型的函數和函數中使用模型而沒有圓形問題?我檢查了與我的問題類似的問題,但我仍然不知道要解決此問題。

models.py

from django.contrib.auth.models import User 
from django.core.urlresolvers import reverse 
from django.db import models 
from .middleware.current_user import get_current_user 
from shortener.utils import create_shortcode 
from django.conf import settings 
CODE_MAX_LENGTH = getattr(settings, 'CODE_MAX_LENGTH', 16) 


class Shortener(models.Model): 
    url = models.URLField() 
    code = models.CharField(unique=True, blank=True, max_length=CODE_MAX_LENGTH) 
    author = models.ForeignKey(User, blank=True, null=True) # Allow anonymous 
    created = models.DateTimeField(auto_now_add=True) 
    modified = models.DateTimeField(auto_now=True) 
    active = models.BooleanField(default=True) 

    def save(self, *args, **kwargs): 
     if not self.pk: 
      self.author = get_current_user() 

      if self.code in [None, ""]: 
       self.code = create_shortcode() 
      elif self.code.find(' ') != -1: 
       self.code = self.code.replace(' ', '_') 

      if self.url not in ["http", "https"]: 
       self.url = "http://{0}".format(self.url) 

     super(Shortener, self).save(*args, **kwargs) 

    def __str__(self): 
     return self.url 

    def __unicode__(self): 
     return self.url 

    def get_short_url(self): 
     return reverse("redirect", kwargs={'code': self.code}) 

Utils.py

import random 
import string 
from django.conf import settings 
from shortener.models import Shortener 
SIZE = getattr(settings, 'CODE_GENERATOR_MAX_SIZE', 12) 


def code_generator(size=SIZE): 
    return ''.join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for _ in range(size)) 


def create_shortcode(): 
    code = code_generator() 

    if Shortener.objects.filter(code=code).exists(): 
     create_shortcode() 

    return code 

回溯:

Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x037EAB28> 
Traceback (most recent call last): 
    File "C:\Users\loc\shortener\lib\site-packages\django\utils\autoreload.py", line 226, in wrapper 
    fn(*args, **kwargs) 
    File "C:\Users\loc\shortener\lib\site-packages\django\core\management\commands\runserver.py", line 113, in inner_run 
    autoreload.raise_last_exception() 
    File "C:\Users\loc\shortener\lib\site-packages\django\utils\autoreload.py", line 249, in raise_last_exception 
    six.reraise(*_exception) 
    File "C:\Users\loc\shortener\lib\site-packages\django\utils\six.py", line 685, in reraise 
    raise value.with_traceback(tb) 
    File "C:\Users\loc\shortener\lib\site-packages\django\utils\autoreload.py", line 226, in wrapper 
    fn(*args, **kwargs) 
    File "C:\Users\loc\shortener\lib\site-packages\django\__init__.py", line 27, in setup 
    apps.populate(settings.INSTALLED_APPS) 
    File "C:\Users\loc\shortener\lib\site-packages\django\apps\registry.py", line 108, in populate 
    app_config.import_models(all_models) 
    File "C:\Users\loc\shortener\lib\site-packages\django\apps\config.py", line 199, in import_models 
    self.models_module = import_module(models_module_name) 
    File "E:\Python\Python35-32\lib\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 "C:\Users\loc\PycharmProjects\DjangoURLShortener\shortener\models.py", line 4, in <module> 
    from shortener.utils import create_shortcode 
    File "C:\Users\loc\PycharmProjects\DjangoURLShortener\shortener\utils.py", line 4, in <module> 
    from shortener.models import Shortener 
ImportError: cannot import name 'Shortener' 
+3

爲什麼你有這個在一個單獨的模塊呢?似乎它應該是Shortener模型中的一種方法。 –

回答

2

簡短回答:create_shortcode實現移動到models.py模塊,它只是3行代碼在那裏生成代碼,並且避免了循環導入。使用self.objects.filter(...)模型和Shortener.save方法執行濾波器。

較長的答案:uuid模塊和uuid.uuid4功能(比寫一個可能實施馬車自己),用於生成唯一代碼更好。目前,您正在生成12個字符或12個字節的隨機代碼,並且UUID模塊可以爲您創建16個字節的代碼。如果你想啓用用戶可定義或可替代的代碼,但希望自動生成非常獨特的代碼:

code = models.CharField(unique=True, max_length=16, default=uuid.uuid4) 
相關問題