postgresql 提交add表单卡在请求循环中,不返回任何错误或日志,也不将值保存在数据库中

lztngnrs  于 2023-01-17  发布在  PostgreSQL
关注(0)|答案(1)|浏览(77)

我尝试通过django管理添加新文档,当我提交表单时,网页发送了一个添加请求,并在控制台显示whois sender= <class 'my_apps.document.models.Document'> is super = <django.db.models.query_utils.DeferredAttribute object at 0x000002058684C400>时卡住了
models.py

#  document/models.py

from pustakalaya_apps.audio.models import Audio
from pustakalaya_apps.video.models import Video
from .search import DocumentDoc

from django.contrib.contenttypes.models import ContentType
from star_ratings.models import Rating

import datetime
date = datetime.datetime.now()
logger = logging.getLogger('app.logger')



class FeaturedItemManager(models.Manager):
    def get_queryset(self):
        return super(FeaturedItemManager, self).get_queryset().filter(published="yes", featured="yes").order_by("-updated_date")[:10]

def accessibleuploadpath(instance, filename):
    formatted_filename = ''.join(letter for letter in filename.replace(' ', '_') if letter.isalnum() or letter == '_')
    directory_path = "uploads/accessibility/documents/{}/{}_{}/{}".format(
        time.strftime("%Y/%m/%d"),
        "_".join(formatted_filename.split(" ")),
        str(uuid.uuid4())[:8],
        filename
    )
    return directory_path

class Document(AbstractItem, HitCountMixin):
    """Book document type to store book type item
    Child class of AbstractItem
    """

    ITEM_INTERACTIVE_TYPE = (
        ("yes", _("Yes")),
        ("NA", _("Not applicable")),
    )

    DOCUMENT_TYPE = (
        ("book", _("Book")),
        ("working paper", _("Working paper")),
        ("thesis", _("Thesis")),
        ("journal paper", _("Journal paper")),
        ("technical report", _("Technical report")),
        ("article", _("Article")),
        ("exam sets", _("Exam sets"))

    )

    DOCUMENT_FILE_TYPE = (
        ("ppt", _("PPT")),
        ("doc", _("Doc")),
        ("docx", _("Docx")),
        ("pdf", _("PDF")),
        ("xlsx", _("Excel")),
        ("epub", _("Epub")),
        ("rtf", _("Rtf")),
        ("mobi", _("Mobi")),
    )

    collections = models.ManyToManyField(
        Collection,
        verbose_name=_("Add to these collections"),
    )

    document_type = models.CharField(
        _("Document type"),
        max_length=40,  # TODO: Change to match the exact value.
        choices=DOCUMENT_TYPE,
    )

    document_file_type = models.CharField(
        _("Document file format"),
        choices=DOCUMENT_FILE_TYPE,
        max_length=23,
        default="pdf"
    )

    document_series = models.ForeignKey(
        "DocumentSeries",
        verbose_name=_("Series"),
        on_delete=models.SET_NULL,
        blank=True,
        null=True
    )

    education_levels = models.ManyToManyField(
        EducationLevel,
        verbose_name=_("Education Levels"),
        blank=True
    )

    grades_subjects_chapters = models.ManyToManyField(
        GradeSubjectChapter,
        verbose_name=_("Grade>Subject>Chapter"),
        blank=True
    )

    languages = models.ManyToManyField(
        Language,
        verbose_name=_("Language(s)"),
        blank=True
    )

    document_interactivity = models.CharField(
        verbose_name=_("Interactive"),
        max_length=15,
        choices=ITEM_INTERACTIVE_TYPE,
        blank=True,
        default="NA"
    )

    # This field should be same on all other model to make searching easy in search engine.
    type = models.CharField(
        max_length=255, editable=False, default="document"
    )

    document_total_page = models.CharField(
        verbose_name=_("Total Pages"),
        blank=True,
        validators=[validate_number],
        max_length=7
    )

    document_authors = models.ManyToManyField(
        Biography,
        verbose_name=_("Author(s)"),
        related_name="authors",
        blank=True,
    )

    document_editors = models.ManyToManyField(
        Biography,
        verbose_name=_("Editor(s)"),
        related_name="editors",
        blank=True,
    )

    document_translator = models.ManyToManyField(
        Biography,
        verbose_name=_("Translator(s)"),
        related_name="translators",
        blank=True,
    )

    document_illustrators = models.ManyToManyField(
        Biography,
        verbose_name=_("Illustrator"),
        related_name="illustrators",
        blank=True
    )

    publisher = models.ManyToManyField(
        Publisher,
        verbose_name=_("Publisher name"),
        related_name="publisher",
        blank=True,

    )

    # Better to have plural name
    keywords = models.ManyToManyField(
        Keyword,
        verbose_name=_("Select list of keywords"),
        blank=True

    )

    license = models.ForeignKey(
        LicenseType,
        on_delete=models.SET_NULL,
        verbose_name=_("license"),
        blank=True,
        null=True,

    )

    thumbnail = models.ImageField(
        upload_to="uploads/thumbnails/document/%Y/%m/%d",
        max_length=255,
        blank=True,
        help_text=_("maximum size of thumbnail should be 255px by 300px")
    )

    sponsors = models.ManyToManyField(
        Sponsor,
        verbose_name=_("Sponsor"),
        blank=True,

    )

    submitted_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        editable=False,
        null=True
    )

    # Manager to return the featured objects.
    objects = models.Manager()
    featured_objects = FeaturedItemManager()

    # View count properties.
    hit_count_generic = GenericRelation(
        HitCount, object_id_field='object_pk',
        related_query_name='hit_count_generic_relation')

    class Meta:
        ordering = ('title',)

    def save(self):
        if self.thumbnail == None or self.thumbnail == '':
            filename = ''.join(letter for letter in self.title.replace(' ', '_') if letter.isalnum() or letter == '_')
            thumbnail = "uploads/thumbnails/document/{}/{}.jpg".format(time.strftime("%Y/%m/%d"), filename)
            self.thumbnail = thumbnail
            print(settings.MEDIA_ROOT)
            print(settings.STATIC_ROOT)
            super(Document, self).save()
        else:
            super(Document, self).save()

    @property
    def getauthors(self):
        author_list = [(author.getname, author.pk) for author in self.document_authors.all()]
        return author_list or [None]  # If emtpy, return something otherwise it will break elastic index while searching.

    @property
    def get_view_count(self):
        try:
            hitcount = HitCount.objects.get(object_pk=self.id)
            # print('Indexing hitcount................................................', hitcount.hits)
            return hitcount.hits or 0
        except HitCount.DoesNotExist:
            # print('Does not exists............................................... 0')
            return 0

    def get_similar_items(self):
        from pustakalaya_apps.video.models import Video
        from pustakalaya_apps.audio.models import Audio

        documents = Document.objects.filter(published='yes', keywords__in=[keyword.id for keyword in self.keywords.all()])
        audios = Audio.objects.filter(published='yes', keywords__in=[keyword.id for keyword in self.keywords.all()])
        videos = Video.objects.filter(published='yes', keywords__in=[keyword.id for keyword in self.keywords.all()])
        all_items = chain(documents, audios, videos)
        item_counter = collections.Counter(all_items)
        return chain(item_counter.most_common(6))

    def __str__(self):
        return self.title

    def doc(self):
        """Create and return document object"""

        item_attr = super(Document, self).doc()
        document_attr = dict(
            **item_attr,
            type=self.type,
            education_levels=[education_level.level for education_level in self.education_levels.all()],
            grades=[grade_subject_chapter.gradesubject.grade.name for grade_subject_chapter in
                    self.grades_subjects_chapters.all()],
            subjects=[grade_subject_chapter.gradesubject.subject.name for grade_subject_chapter in
                      self.grades_subjects_chapters.all()],
            chapters=[grade_subject_chapter.chapter.name for grade_subject_chapter in
                      self.grades_subjects_chapters.all()],
            communities=[collection.community_name for collection in self.collections.all()],
            collections=[collection.collection_name for collection in self.collections.all()],
            collections_ids=[collection.pk for collection in self.collections.all()],
            languages=[language.language.lower() for language in self.languages.all()],
            publisher=[publisher.publisher_name for publisher in self.publisher.all()],
            sponsors=[sponsor.name for sponsor in self.sponsors.all()],  # Multi value # TODO some generators
            keywords=[keyword.keyword for keyword in self.keywords.all()],
            # License type
            license_type=self.license.license if self.license else None,
            # Document type specific
            thumbnail=self.thumbnail.name,
            # document_identifier_type=self.document_identifier_type,
            document_file_type=self.document_file_type,
            document_type=self.document_type,
            document_authors=[
                author.getname for author in self.document_authors.all()
                ],
            document_illustrators=[
                illustrator.getname for illustrator in self.document_illustrators.all()
                ],  # Multi value TODO generator
            document_editors=[
                editor.getname for editor in self.document_editors.all()
                ],  # Multi value
            document_translator=[
                translator.getname for translator in self.document_translator.all()
            ],
            document_total_page=self.document_total_page,
            # Document interactivity
            document_interactivity=self.document_interactivity,
            # author with name and id.
            author_list=self.getauthors,
            url=self.get_absolute_url()

        )

        # Create ES Document for indexing
        obj = DocumentDoc(
            **document_attr,
        )

        return obj

    @property
    def get_publisher_name(self):
        """
        Method that return publisher name to index in elastic search server
        If publisher name is None return empty string
        :return:
        """

        if self.publisher is None:
            return " "

        return self.publisher.publisher_name

    def delete_index(self):
        try:
            self.doc().delete()
        except NotFoundError:
            # TODO:
            pass

    def index(self):
        """index or update a document instance to elastic search index server"""
        # Index to index server if any doc is not empty and published status is "yes"
        if self.published == "no":
            # delete this if the published is set to no form
            self.delete_index()
        else:
            #save only when published is yes
            self.doc().save()

    def bulk_index(self):
        # Do bulk index if doc item is not empty.
        return self.doc().to_dict(include_meta=True)

    def get_absolute_url(self):
        return reverse("document:detail_without_slug", kwargs={ "pk": self.pk})
        # return reverse("document:detail", kwargs={"title": slugify(self.title), "pk": self.pk})

    def get_dashboard_edit_url(self):
        return reverse("dashboard:document_update", kwargs={"pk": self.pk})

    def get_dashboard_delete_url(self):
        return reverse("dashboard:document_delete", kwargs={"pk": self.pk})

    def get_admin_url(self):
        return urlresolvers.reverse("admin:%s_%s_change" %(self._meta.app_label, self._meta.model_name), args=(self.pk,))

    def document_title(self):
        return self.title

    def published_yes_no(self):
        return self.published

    def featured_yes_no(self):
        return self.featured

    def updated_date_string(self):
        return self.updated_date

    def submited_by(self):
        return self.submitted_by

    def document_link_name(self):
        return self.link_name;

    def get_fileuploads(self):
        return self.documentfileupload_set.all()

class UnpublishedDocument(Document):
    """
    This is the proxy model of Document,
    Used in admin.py to display the list of unpublished document.
    """
    class Meta:
        proxy = True

class FeaturedDocument(Document):
    """
    This is the proxy model of Document,
    Used in admin.py to display the list of unpublished document.
    """
    class Meta:
        proxy = True

class DocumentSeries(AbstractSeries):
    """BookSeries table inherited from AbstractSeries"""

    class Meta:
        verbose_name_plural = _("Document series")

    def __str__(self):
        return self.series_name

def uploadpath(instance, filename):
    formatted_filename = ''.join(letter for letter in instance.file_name.replace(' ', '_') if letter.isalnum() or letter == '_')
    directory_path = "uploads/documents/{}/{}_{}/{}".format(
        time.strftime("%Y/%m/%d"),
        "_".join(formatted_filename.split(" ")),
        str(uuid.uuid4())[:8],
        filename
    )
    return directory_path

class DocumentFileUpload(AbstractTimeStampModel):
    """Class to upload the multiple document objects"""

    file_name = models.CharField(
        _("File name"),
        max_length=255,
        blank=True,
        default=""
    )

    document = models.ForeignKey(
        Document,
        on_delete=models.CASCADE
    )

    publisher = models.ManyToManyField(
        Publisher,
        verbose_name=_("Publisher(s)"),
        blank=True,
    )

    upload = models.FileField(
        upload_to=uploadpath,
        max_length=255
    )

    total_pages = models.IntegerField(default=0, editable=False)

    def get_files(self):
        images = []
        for i in range(self.total_pages):
            path, file_name = os.path.split(self.upload.url)
            images.append("{}/{}.png".format(path, i))

        return images

    def __str__(self):
        return self.file_name

    class Meta:
        ordering=['created_date']

def documentfileupload_post_save(sender, instance=False, **kwargs):
    """This post save function creates a thumbnail for the Document"""
    documentfile = DocumentFileUpload.objects.filter(document=instance.document)
    for file in documentfile:
        filename = ''.join(letter for letter in file.document.title.replace(' ', '_') if letter.isalnum() or letter == '_')
        if file.document.thumbnail == "uploads/thumbnails/document/{}/{}.jpg".format(time.strftime("%Y/%m/%d"), filename):
            path = os.path.join(settings.MEDIA_ROOT, "uploads/thumbnails/document/{}".format(time.strftime("%Y/%m/%d")))
            if not os.path.exists(path):
                try:
                    logger.info('Making required folder structures for converted thumbnail uploads.')
                    os.makedirs(path)
                    logger.info('Folder structures made successfully.')
                except Exception as e:
                    logger.info('Got exception: {}'.format(e))
                    pass
            
            logger.info('Creating Document Thumbnail...')
            file_path = settings.MEDIA_ROOT + str(file.upload)
            pages = convert_from_path(file_path, 50)[0]
            upload_path = settings.MEDIA_ROOT + str(file.document.thumbnail)
            pages.save(upload_path, 'JPEG')
            logger.info('Document Thumbnail created successfully...')

# Hook up the signal
post_save.connect(documentfileupload_post_save, sender=DocumentFileUpload)

def add_file_name(sender, instance=False, **kwargs):
    logger = logging.getLogger('app.logger')

    try:
        if not instance.file_name:
            base = os.path.basename(instance.upload.name)
            filename = os.path.splitext(base)[0].capitalize()
            instance.file_name = filename
            logger.info('File name field feeded.')
    except Exception as e:
        logger.error('Failed to feed file_name field: {}'.format(e))

pre_save.connect(add_file_name, sender=DocumentFileUpload)

class DocumentLinkInfo(LinkInfo):
    document = models.ForeignKey(
        Document,
        verbose_name=_("Link"),
        #on_delete=models.CASCADE,

    )
    publisher = models.ManyToManyField(
        Publisher,
        verbose_name=_("Publisher(s)"),
        blank=True,
    )

    def __str__(self):
        return self.link_name

    class Meta:
        ordering=['created_date']

class DocumentIdentifier(AbstractTimeStampModel):
    identifier_type = models.CharField(
        verbose_name=_("Identifier Type"),
        max_length=8,
        blank=True,
        choices=(
            ("issn", _("ISSN")),
            ("ismn", _("ISMN")),
            ("govt_doc", _("Gov't Doc")),
            ("uri", _("URI")),
            ("isbn", _("ISBN"))
        )
    )
    identifier_id = models.CharField(
        _("Identifier ID"),
        blank=True,
        max_length=30
    )

    document = models.OneToOneField(
        Document,
        verbose_name=_("document"),
        on_delete=models.CASCADE,
    )

    def __str__(self):
        return self.identifier_type

signals.py

from __future__ import print_function
import os
from django.dispatch import receiver
from django.db import transaction
from django.db.models.signals import post_save, pre_delete, m2m_changed, post_delete
from .models import Document, DocumentFileUpload
from ****_apps.core.utils import send_mail_on_user_submission, write_gradewise_to_file
from django.contrib.auth.models import User

@receiver(m2m_changed, sender=Document.keywords.through)
@receiver(m2m_changed, sender=Document.document_authors.through)
@receiver(m2m_changed, sender=Document.education_levels.through)
@receiver(m2m_changed, sender=Document.document_illustrators.through)
@receiver(m2m_changed, sender=Document.document_editors.through)
@receiver(m2m_changed, sender=Document.collections.through)
@receiver(m2m_changed, sender=Document)
@receiver(post_save, sender=Document)
@transaction.atomic
def index_or_update_document(sender, instance, **kwargs):
    # send an email to user when the document is published.

    # By pass for unpublished items
    # if instance.published == "no":
    #     return
    if instance.published == "yes":
        # added to restrict the if user is super user
        # if not sender is User.is_superuser:
        print("whois sender=",sender,"is super =",User.is_superuser)
        send_mail_on_user_submission(item=instance)

    if instance.license is not None:
        if instance.license:
            instance.license_type = instance.license.license

    # Save or update index
    instance.index()

@receiver(pre_delete, sender=Document)
@transaction.atomic
def delete_document(sender, instance, **kwargs):

     # By pass for unpublished items
    # if instance.published == "no":
    #     return

    # Delete an index first before instance in db.
    instance.delete_index()

@receiver(post_save, sender=DocumentFileUpload)
@transaction.atomic
def create_or_update_documentuploads(sender, instance, **kwargs):
    if instance.document.is_grade_wise == 'yes':
        write_gradewise_to_file(instance.upload.url, 'document', 'save')

@receiver(post_delete, sender=DocumentFileUpload)
@transaction.atomic
def delete_documentuploads(sender, instance, **kwargs):
    if instance.document.is_grade_wise == 'yes':
        write_gradewise_to_file(instance.upload.url, 'document', 'delete')

views.py

def documents(request):
    documents = 1 or Document.objects.all()
    return render(request, 'document/documents.html', {'documents': documents})

search.py

class DocumentDoc(ItemDoc):
    """Elastic search schema for document type"""
    # Document type specific

    thumbnail = Text()
    document_total_page = Long()
    document_file_type = Text()
    document_type = Text()
    document_authors = Text(multi=True)
    document_illustrators = Text(multi=True)  # Multi value TODO generator
    document_editors = Text(multi=True)
    document_interactivity = Text()

    class Meta:
        index = settings.ES_INDEX
        doc_type = "document"

每个必填字段均已填写,数据库已连接,并且已应用正确的迁移。

pftdvrlh

pftdvrlh1#

您应该使save()方法签名与底层方法签名兼容,例如*args**kwargs
但是,您已经有了一个upload_to,因此thumbnail不会是None或空。
如果要自动指定随机文件名,请用途:

from django.utils import timezone
from django.utils.text import slugify

class Document(HitCountMixin, AbstractItem):
    def upload_thumbnail_to(self, filename):
        return f'uploads/thumbnails/document/{timezone.now().strftime("%Y/%m/%d")}/{slugify(self.title)}.jpeg'

    thumbnail = models.ImageField(
        upload_to=upload_thumbnail_to,
        blank=True,
        help_text=_('maximum size of thumbnail should be 255px by 300px'),
    )
    # …

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        print('instance saved')

相关问题