Nützlichkeit für Django-Entwickler

Vorwort

Um diesen Artikel zu schreiben, wurde eine sehr große Materialschicht untersucht, die über das gesamte Internet in Foren, Chats, Blogseiten und im Stackoverflow verteilt ist. Ich habe alles zusammengestellt, da es für mich nützlich sein wird und ich hoffe wirklich, dass auch andere Django-Entwickler mit diesem Material zufrieden sind. Wenn es etwas hinzuzufügen (zu verbessern) oder zu korrigieren gibt, schreiben Sie bitte in die Kommentare oder in Dialoge (private Nachrichten) Habr.





Handler 404 testen

Wenn wir versuchen, den 404-Fehler mit dem angegebenen Debug = True zu testen, erhalten wir einen Standard-Django-Fehlerbericht, in dem der Grund angegeben ist. Mit der folgenden Methode können Sie jedoch überprüfen, ob der 404-Fehler ohne unnötige Sorgen funktioniert. Auf einer Arbeitsseite empfehle ich dringend die Verwendung von Nginx.





  1. Öffnen Sie diese Datei, um die Datei settings.py im Projektverzeichnis zu bearbeiten, und setzen Sie den Wert debug = False





  2. Öffnen Sie im selben Verzeichnis die Datei urls.py zum Bearbeiten und fügen Sie die folgenden Zeilen hinzu:





from django.urls import re_path
from django.views.static import serve #  

re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),

re_path(r'^static/(?P<path>.*)$', serve, {'document_root': settings.STATIC_ROOT}),
      
      



debug false, , , django nginx, , , 404 Django localhost, python manage.py runserver .





, , Python/Django      ,   .

( :

: habrhabr

: pp#6JZ2\a7y=





: , . 





, Worker - FK Experience:





class Worker(models.Model):
    public_cv = models.BooleanField(default=False, verbose_name='Can everyone see your resume ?')
    cv_name = models.CharField(max_length=250, verbose_name='CV name', blank=True)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name='Author', default=0)
	
	# +  

    def __str__(self):
        return self.name

    def publish(self):
        self.published_date = timezone.now()
        self.save()

class Experience(models.Model):
    worker = models.ForeignKey(Worker, on_delete=models.CASCADE)
    title = models.CharField(max_length=200, verbose_name='Position name')

	# +  

    def __str__(self):
        return self.title

    def publish(self):
        self.published_date = timezone.now()
        self.save()

# +  
      
      



, - django-admin, StackedInline:





class ExperienceInstance(admin.StackedInline):
    model = Experience
    extra = 1

@admin.register(Worker)
class PublishWorkers(admin.ModelAdmin):
    inlines = [
        ExperienceInstance,]
      
      



Django-admin, Experience Worker " Experience":





views.py , Experience Experience, Formset:





from django.forms import inlineformset_factory
from django.http import HttpResponseRedirect
from .forms import ExperienceForm


def expformview(request, worker_uid):
    worker = Worker.objects.get(uid=worker_uid)
    ExperienceFormset = inlineformset_factory(
        Worker, Experience, form=ExperienceForm, extra=1, max_num=15, can_delete=True
    )
    if request.method == 'POST':
        formset = ExperienceFormset(request.POST, instance=worker)
        if formset.is_valid():
            formset.save()
            return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

    formset = ExperienceFormset(instance=worker)
    return render(request, 'site/expform.html',
                  {
                      'formset': formset,
                      'worker': worker,
                  }
                  )
      
      



, forms.py ExperienceForm:





class ExperienceForm(forms.ModelForm):
    started = forms.DateField(
        required=False,
        label='Start date',
        widget=forms.TextInput(attrs={'placeholder': 'YYYY-MM-DD'})
    )
    ended = forms.DateField(
        required=False,
        label='End date',
        widget=forms.TextInput(attrs={'placeholder': 'YYYY-MM-DD'})
    )

    class Meta:
        model = Experience
        fields = ('title',
                  'selfedu',
                  )
      
      



HTML. Crispy . {{formset.media}}



WYSIWYG- ckeditor. type="submit"



, :





HTML
{% extends 'site/base.html' %}
{% load crispy_forms_tags %}
{% block content %}
{% if worker.author == request.user%}
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Experience | {{worker}}</title>
   </head>
   <body>
      <center>
         <div class="col-lg-5" style="margin:1em;">
            <nav aria-label="breadcrumb">
               <ol class="breadcrumb">
                   <li class="breadcrumb-item">Basic information</li>
                   <li class="breadcrumb-item active" aria-current="page"><b>Experience</b></li>
                   <li class="breadcrumb-item">Education</li>
                   <li class="breadcrumb-item">Certification</li>
                   <li class="breadcrumb-item">Awards</li>
                   <li class="breadcrumb-item">Projects</li>
               </ol>
            </nav>
         </div>
      </center>
   <h2 align="center" style="margin:1em;">{{worker}}'s Experience form</h2>
      <form method="post">
         {% csrf_token %}
         <div class="row" style="margin:2em 0 2em 0;">
            <div class="col-lg-5 mx-auto">
               {{formset.media}}
               {{formset|crispy}}
            </div>
             <div class="col-lg-12">
                 <center><button type="submit" class="btn btn-outline-warning">Save & Add</button>
                 <a href="edu"><button type="button" class="btn btn-outline-success">Next > Education</button></a></center>
             </div>
         </div>
      </form>
   </body>
</html>
{%else%}
      <div class="row">
         <div class="col-lg-12" style="margin-top:6em;">
            <center>
               <h2>You have not access to this section</h2>
            </center>
         </div>
      </div>
      {%endif%}
{% endblock %}
      
      



:





PDF ( )

, HTML PDF  XHTML2PDF; venv :





pip install xhtml2pdf
      
      



views.py:





from xhtml2pdf import pisa

def render_pdf_view(request, worker_uid):
    template_path = 'site/pdf.html'
    worker = Worker.objects.get(uid=worker_uid)
    exp = Experience.objects.filter(worker=worker)
    context = {
        'worker': worker,
        'exp': exp,
    }
    response = HttpResponse(content_type='application/pdf')

    response['Content-Disposition'] = 'filename="%s_%s.pdf"' % (worker.name, worker.created_date.strftime('%Y-%m-%d')) #     PDF : _--
    #     
    template = get_template(template_path)
    html = template.render(context)

    #  PDF
    pisa_status = pisa.CreatePDF(html, dest=response, )
    #  
    if pisa_status.err:
        return HttpResponse('We had some errors <pre>' + html + '</pre>')
    return response
      
      



HTML , , PDF , <style></style>



.





Damit russische Zeichen in der exportierten PDF-Datei korrekt angezeigt werden, möchten Sie eine Schriftart herunterladen, die die kyrillischen (russischen) Buchstaben unterstützt, und diese in die statische Datei / fonts / einfügen Verzeichnisse, wie in meinem Fall, sieht der Pfad folgendermaßen aus :  /var/www/cvmaker/static/fonts/arial.ttf



, und <style/>



fügen Sie zwischen den Tags Folgendes hinzu:





@font-face {
         font-family: 'sans-serif';
         src: url("/var/www/cvmaker/static/fonts/arial.ttf");
         }
         body{
         font-family: "sans-serif";
         }
      
      



Daher sehen wir in der exportierten PDF-Datei anstelle von schwarzen Quadraten anstelle von russischen Buchstaben normale kyrillische Zeichen:








All Articles