Django: проблема с MultiValueDictKeyError с функцией загрузки - PullRequest
0 голосов
/ 28 ноября 2018

Я хотел бы получить вашу помощь, чтобы улучшить мой код и получить возможность загружать документы двумя способами.

Пояснения:

Первый метод позволяет проверить некоторые документы, и пользователь должен заполнить email field.После этого появляется modal с предварительно заполненными полями в соответствии с предыдущим адресом электронной почты, поскольку набор запросов выполняется с filter на email adress

Это основной процесс загрузки документов.

Второй способ отличается.Я генерирую уникальную гиперссылку с идентификатором документа в URL.Но благодаря этому мне не нужен электронный адрес, как раньше.

Мои коды:

Это мой файл model.py:

class Document(models.Model):

    code = models.CharField(max_length=25, verbose_name=_('code'), unique=True, null=False, blank=False)
    language = models.CharField(max_length=2, verbose_name=_('language'), choices=LANGUAGE_CHOICES, null=False, blank=False)
    format = models.CharField(max_length=10, verbose_name=_('format'), choices=FORMAT_CHOICES, null=False, blank=False)
    title = models.CharField(max_length=512, verbose_name=_('title'), null=False, blank=False)
    publication = models.ForeignKey(Publication, verbose_name=_('publication title'), related_name='documents')
    upload = models.FileField(upload_to='media/files/', validators=[validate_file_extension], verbose_name=_('document file'), null=False, blank=False)

    class Meta:
        verbose_name = _('document')
        verbose_name_plural = _('documents')

class Customer(EdqmTable):
    email = models.EmailField(max_length=150, verbose_name=_('e-mail'), null=False)
    first_name = models.CharField(max_length=70, verbose_name=_('first name'), null=False)
    last_name = models.CharField(max_length=70, verbose_name=_('last name'), null=False)
    country = models.ForeignKey(Country, verbose_name=_('country'))
    institution = models.CharField(max_length=255, verbose_name=_('institution'), null=True)

    class Meta:
        verbose_name = _('customer')
        verbose_name_plural = _('customers')

    def __str__(self):
        return f"{self.email}"

Это мой файл forms.py:

class CustomerForm(forms.ModelForm):
    class Meta:
        model = Customer
        fields = ['email', 'first_name', 'last_name', 'country', 'institution']
        widgets = {
            'email': forms.TextInput(attrs={'placeholder': _('name@example.com')}),
            'first_name': forms.TextInput(attrs={'placeholder': _('First Name')}),
            'last_name': forms.TextInput(attrs={'placeholder': _('Last Name')}),
            'institution': forms.TextInput(attrs={'placeholder': _('Agency, company, academic or other affiliation')}),
        }

    def __init__(self, *args, **kwargs):
        customer_email = kwargs.pop('customer_email', None)

        super(CustomerForm, self).__init__(*args, **kwargs)
        self.fields['country'].empty_label = _('Select a country')
        self.fields['country'].queryset = self.fields['country'].queryset.order_by('name')
        self.fields['email'].required = True
        self.fields['first_name'].required = True
        self.fields['last_name'].required = True
        self.fields['country'].required = True
        self.fields['institution'].required = False

        query_customer_email = Customer.objects.filter(email__iexact=customer_email)

        if customer_email is not None:
            if query_customer_email.exists():
                self.fields['email'].initial = customer_email
                self.fields['first_name'].initial = query_customer_email.distinct()[0].first_name
                self.fields['last_name'].initial = query_customer_email.distinct()[0].last_name
                self.fields['country'].initial = query_customer_email.distinct()[0].country_id
                self.fields['institution'].initial = query_customer_email.distinct()[0].institution
                self.fields['email'].widget.attrs['readonly'] = True
                self.fields['first_name'].widget.attrs['readonly'] = True
                self.fields['last_name'].widget.attrs['readonly'] = True
                self.fields['country'].widget.attrs['readonly'] = True
            else:
                self.fields['email'].initial = customer_email

Это часть моего файла шаблона:

<div class="row">
    <div class=" col-md-5">
        <label for="primary">Email address</label>
        <input type="email" class="form-control" id="email-download-document" name="EmailDownloadDocument"
                 placeholder="Enter email address to get document(s)">
     </div>
 </div>
 <br>
 <div class="row">
     <div class=" col-md-5">
         <input id="document-choice-button" type="submit" class="btn btn-default" name="DocumentSelected"
                 value="{% trans 'Send to my email' %}"/>
     </div>
 </div>

Теперь вы можете найти мой файл views.py:

#Part according to the first method
class HomeView(CreateView, FormView):
    ...
    def get_form_kwargs(self):
        kwargs = super(HomeView, self).get_form_kwargs()
        if "DocumentSelected" in self.request.GET:
            customer_email = self.request.GET['EmailDownloadDocument']
            kwargs['customer_email'] = customer_email
        return kwargs

# Part according to the second method
class MyRedirectView(RedirectView):

    def get_redirect_url(self, *args, **kwargs):
        q = QueryDict(mutable=True)
        q['DocumentChoice'] = self.kwargs['code']
        q['DocumentSelected'] = 'Send to my email'
        my_site = settings.MY_SITE_URL

        if my_site == 'http://localhost:8000':
            return f"{my_site}/app/home?{q.urlencode()}"
        else:
            return f"{my_site}/dev3/app/app/home?{q.urlencode()}"

И, наконец, мой файл urls.py:

urlpatterns = [
    url(r'^app/home$', HomeView.as_view(), name='app-home'),
    ...
    url(r'^app/direct/download/(?P<code>[\w\.-]+)/$',MyRedirectView.as_view(), name='go-to-direct-download'),

Проблема:

Первый метод работает отлично!У меня нет никаких проблем с этой частью.

Но вторая не работает так, как я хочу, потому что я не знаю, как я могу избежать части электронной почты.Потому что это прямая ссылка, и я должен отобразить модальный, но с пустой формой, потому что все люди могут иметь доступ по этой ссылке.Поэтому мне не нужно получать данные предварительной загрузки.

Например:

1-й метод:

[! [Введите описание изображения здесь] [1]] [1]

2-й метод:

При использовании этого метода мой URL-адрес, например:

http://localhost:8000/app/direct/download/PUBSD-0001-FR-PDF-1714

становится:

http://localhost:8000/app/home?DocumentChoice=PUBSD-0001-FR-PDF-1714&DocumentSelected=Send+to+my+email

Но я получаю эту проблему:

Тип исключения: MultiValueDictKeyError в / app / home Значение исключения: "'EmailDownloadDocument'"

И я не хочу использоватьэлектронная почта в этом методе.

Большое спасибо!

РЕДАКТИРОВАТЬ:

Я нашел кое-что:

Я изменил свойget_form_kwargs() метод, подобный этому:

def get_form_kwargs(self):
    kwargs = super(HomeView, self).get_form_kwargs()
    if "DocumentSelected" in self.request.GET:
        customer_email = self.request.GET.get('EmailDownloadDocument', '')
        kwargs['customer_email'] = customer_email
    return kwargs

Кажется, сейчас работает, это правильно?

...