Как передать текущий идентификатор пользователя как скрытое поле в форме Django? - PullRequest
2 голосов
/ 14 февраля 2012

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

Моя модель:

class Portfolios(models.Model):
    id = models.AutoField(primary_key=True)
    port_name = models.CharField(max_length=135, blank=True)
    port_type = models.ForeignKey(PortType, null=True, db_column='port_type', blank=True)
    user = models.ForeignKey(User)

    def __unicode__(self):
        return self.port_name;

class Meta:
    db_table = u'tbl_portfolios'

Моя форма:

class PortfoliosCreateForm(ModelForm):
    class Meta:
        model = Portfolios;

Мой шаблон:

<form action="" method="post">
    {% csrf_token %}
    {% for field in form %}
        <div class="create_form_field">
            {{ field.errors }}
            {{ field.label_tag }}: {{ field }}
        </div>
    {% endfor %}
    <input type="submit" value="Create" /></p>
</form>

Я вызываю шаблон, используя общий вид создания:

url(
    r'^portfolios/create/$',
    'django.views.generic.create_update.create_object',
    dict(
        form_class=PortfoliosCreateForm,
        post_save_redirect='/',
        template_name='portfolios/create.html'
    )

),

Как мне лучше всего встроить идентификатор пользователя в эту форму, чтобы он передавал скрытое поле? Или я должен просто передать фиктивное поле и ввести значение в пользовательскую функцию сохранения?

Редактировать: Пользовательская модель - это встроенная пользовательская модель Django.

Спасибо

Ответы [ 2 ]

13 голосов
/ 14 февраля 2012

Гораздо безопаснее получить текущего пользователя из запроса после отправки формы. Вы можете переписать общий вид примерно так:

from django.shortcuts import redirect, render

def create_portfolio(request):
    if request.method == 'POST':
        form = PortfoliosCreateForm(request.POST)
        if form.is_valid():
            portfolio = form.save(commit=False)
            portfolio.user = request.user  # The logged-in user
            portfolio.save()
            return redirect('/')
    else:
        form = PortfoliosCreateForm()
    return render(request, 'portfolios/create.html', {'form': form})


url(r'^portfolios/create/$', create_portfolio)


class PortfoliosCreateForm(ModelForm):
    class Meta:
        model = Portfolios;
        exclude = ['user']   # Will be taken from the request
0 голосов
/ 16 апреля 2015

Установка всех в общем виде НЕ является хорошей практикой, потому что:

  1. вынуждает вас изменить логику в классе form, что может добавить дыры ограничений, так что вы можете сохранить плохие данные в базу данных, если вы попытаетесь создать объект где-то снаружи на общий вид и
  2. добавляет дополнительную бесполезную сложность в общий вид. Представление похоже на контроллер, оно должно знать, что ВОЗ отвечает за проверку / сохранение данных, и просто передать их этой стороне. Он НЕ должен знать, КАК объекты связаны и проверены, и
  3. это заставляет вас распространять ваш код здесь и там.

На мой взгляд, лучшим подходом может быть:

модель

class Book(models.Model):
    # ...
    author = models.ForeignKey(Author, related_name='books')

    # ...

форма

class BookForm(forms.ModelForm):

class Meta:
    model = Book
    # ...

    widgets = {
        'author': forms.HiddenInput(),
        # ...
    }

    # ...

вид

def create(request, author_id):
    author = get_object_or_404(Author, pk=author_id)
    form = BookForm(request.POST or None, initial={'author': author.id})
    if request.method == "POST":
        if form.is_valid():
            form.save()
            return redirect('/')

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

...