Проверка уникальности полностью завершается неудачей, если одно из полей исключено из формы - PullRequest
0 голосов
/ 31 октября 2009

У меня есть модель Меню:

class Menu(models.Model):
    loja = models.ForeignKey(Loja, related_name='menus')
    nome = models.CharField(max_length=30)
    ordenacao = models.IntegerField(blank=True, null=True)

    class Meta:
        ordering = ('ordenacao',)
        #prevent equally named menus within a store(loja)
        unique_together = ('loja', 'nome')

    def __unicode__(self):
        return self.nome 

Форма меню:

class MenuForm(ModelForm):
    class Meta:
        model = Menu
        exclude =('loja', 'ordenacao',)

Добавить вид меню:

def addmenu(request, s_loja):
    loja = get_object_or_404(Loja, slug=s_loja)
    if not loja.activo:
        return render_to_response('painelcontrolo/loja_detail.html', {
            'notificacoes': ['Loja está definida como inactivo.', \
                             'Alterações não permitidas']})
    if request.method == 'POST':
        menu = Menu(loja=loja)
        form = MenuForm(request.POST, instance=menu)
        if form.is_valid():
            menu_existe = Menu.objects.\
                          filter(nome=form.cleaned_data['nome']).\
                          filter(loja=loja)
            if menu_existe:
                return render_to_response(\
                    'painelcontrolo/loja_detail.html', {
                        'notificacoes': ['Já existe um menu com esse nome']
                        })
            form.save()
            return render_to_response(\
                    'painelcontrolo/loja_detail.html', {
                        'notificacoes': ['Menu adicionado']
                        })
    else:
        form = MenuForm()
    return render_to_response('form_as_p.html', {
        'form': form
    })

Ошибка: (больше не возникает с добавленной проверкой в ​​представлении addmenu)

Request Method:     POST
Request URL:    http://127.0.0.1:8000/painel/bispos/addmenu/
Exception Type:     IntegrityError
Exception Value:    columns loja_id, nome are not unique

Вопрос: Форма действительна, но модель не существует, если в базе данных уже существует nome + loja_id. Нужно ли добавить эту проверку в другом месте? А где?

редактирование: Я написал проверку для представления, и он передает уведомление в шаблон, и это нормально, но не идеально. Я хотел бы повторно отобразить форму с пользовательским вводом, чтобы дать возможность исправить то, что не так, без потери этой информации. Есть ли способ сделать это?

Ответы [ 3 ]

2 голосов
/ 31 октября 2009

Я бы просто оставил loja в форме, но сделал бы его скрытым полем.

class MenuForm(ModelForm):
    loja = models.ModelChoiceField(Loja.objects.all(), widget=forms.HiddenInput)

    class Meta:
        model = Menu
        exclude =('ordenacao',)

Вам, вероятно, придется изменить свое мнение, чтобы позвонить на getloja() независимо от того, является ли запрос постом или получен. Вы никогда не объясняете, КАК getloja() решает, что является правильным экземпляром ...

@login_required
def addmenu(request, s_loja):
    if request.method == 'POST':
        form = MenuForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/painel/profile/')
    else:
        loja = getloja(request, s_loja) #simply retrieves the correct loja instance
        menu = Menu(loja=loja)
        form = MenuForm(instance=menu)
    return render_to_response('form_as_p.html', {
           'form': form,})
1 голос
/ 31 октября 2009

Хорошо, это лучшее, что я мог придумать. Это дает ошибку в форме и, кажется, работает нормально.

@login_required
def addmenu(request, s_loja):
    loja = get_object_or_404(Loja, slug=s_loja)
    if not loja.activo:
        return render_to_response('painelcontrolo/loja_detail.html', {
            'notificacoes': ['Loja está definida como inactivo.', \
                             'Alterações não permitidas']})
    if request.method == 'POST':
        menu = Menu(loja=loja)
        form = MenuForm(request.POST, instance=menu)
        if form.is_valid():
            menu_existe = Menu.objects.\
                          filter(nome=form.cleaned_data['nome']).\
                          filter(loja=loja)
            if not menu_existe:
                form.save()
                return render_to_response('painelcontrolo/loja_detail.html', {
                        'notificacoes': ['Menu adicionado']
                        })
            else:
                form._errors['nome'] = ErrorList(\
                    ['Um menu com esse nome já existe'])
    else:
        form = MenuForm()
    return render_to_response('form_as_p.html', {
        'form': form,
    })
0 голосов
/ 31 октября 2009

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

Другими словами, "form.is_valid ()" не собирается сохранять в базу данных, и это единственный способ узнать, работает ли сохранение.

Вам придется поймать это самостоятельно, я в этом уверен, но "unique_together" уже выполняет свою работу.

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