Модель Джанго (с исключенным полем) - PullRequest
9 голосов
/ 18 апреля 2011

У меня есть образец формы:

class AdminDiscountForm(ModelForm):  
    class Meta:  
        model = Discount  
        exclude = ('company',)

модель, на которую он указывает:

class Discount(models.Model):
    class Meta:
        verbose_name=_('Discount')
        verbose_name_plural=_('Discounts')
        unique_together = ('company','type')

    company = models.ForeignKey(Company)
    type = models.CharField(max_length=5, choices=DISCOUNT_CHOICES)
    discount = models.DecimalField(max_digits=7, decimal_places=2, verbose_name=_('Discount'))

Форма исключает поле «компания», поскольку пользователь уже выбрал его с помощью пользовательского интерфейса.

Я планирую сделать:

company = blah
if form.is_valid():
    obj = form.save(commit=False)
    obj.company = company
    obj.save()

Проблема в том, что комбинация «компания» и «тип» должна быть уникальной (отсюда и «уникальный_все»). Это применяется в базе данных, поэтому django не волнует. Мне нужно расширить метод clean () этой формы, чтобы проверить уникальность как таковую:

def clean(self):
    cleaned_data = self.cleaned_data
    # check for uniqueness of 'company' and 'type'

Проблема здесь в том, что «компании» там нет, потому что она была исключена. Каков наилучший способ вызвать ошибку проверки формы в этом случае?

- редактировать Это только для добавления скидок. Там нет первоначального экземпляра.

Ответы [ 2 ]

12 голосов
/ 18 апреля 2011

Я использую метод Джеммона.Чтобы немного расширить (используя ваш пример):

models.py

class Discount(models.Model):
    class Meta:
        verbose_name=_('Discount')
        verbose_name_plural=_('Discounts')
        unique_together = ('company','type')

    company = models.ForeignKey(Company)
    type = models.CharField(max_length=5, choices=DISCOUNT_CHOICES)
    discount = models.DecimalField(max_digits=7, decimal_places=2, verbose_name=_('Discount'))

forms.py

class AdminDiscountForm(ModelForm):  
    class Meta:  
        model = Discount  
        exclude = ('company',)

views.py

def add_discount(request, company_id=None):
    company = get_object_or_404(Company, company_id)

    discount=Discount(company=company)

    if request.method == 'post':
        form = AdminDiscountForm(request.POST, instance=discount)
        if form.is_valid():
            form.save()
            return HttpResponse('Success')
    else:
        form = AdminDiscountForm(instance=company)

    context = { 'company':company,
                'form':form,}

    return render_to_response('add-discount.html', context,
        context_instance=RequestContext(request))

Это работает путем создания экземпляра вашей модели скидки, а затем привязки вашей формы к этому экземпляру.Этот экземпляр не сохраняется в вашей базе данных, но используется для привязки формы.Эта связанная форма имеет значение для компании связанного экземпляра.Затем он отправляется в ваш шаблон для заполнения пользователем.Когда пользователь отправляет эту форму, и форма проверяется, проверка правильности модели проверит уникальность уникального вместе, определенного в Meta.

См. Model Validation Docs и overriding clean for ModelForms

edit:

Вы можете сделать несколько вещей, чтобы поймать не уникальную запись вместепопытки.

  1. Внутри вашего form.is_valid () вы можете, кроме ошибки целостности, например:

    if request.method == 'post':
        form = AdminDiscountForm(request.POST, instance=discount)
        if form.is_valid():
            try:
                form.save()
                return HttpResponse('Success')
            except IntegrityError:
                form._errors["company"] = "some message"
                form._errors["type"] = "some message"
        else:
            ...
    
  2. Использовать self.instanceчистый метод формы модели для проверки уникальности.

3 голосов
/ 18 апреля 2011

Вы можете попробовать это:

discount = Discount(company = blah)
form = AdminDiscountForm(request.POST, instance=discount)
if form.is_valid():
    discount = form.save()

А документы говорят: по умолчанию метод clean () проверяет уникальность полей, помеченных как ... unique_together

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