Установка владельца объекта с общим представлением create_object в django

Можно ли использовать представление create_object для создания нового объекта и автоматически присваивать request.user в качестве внешнего ключа?

P.E:

class Post(models.Model):
    text = models.TextField()
    author = models.ForeignKey(User)

Я хочу использовать create_object и заполнять автора request.user.

Ответ 1

Во многих отношениях все решения для этого будут больше проблем, чем они того стоят. Это можно назвать взломом. Возможно, обновление django оставит вас высоко и сухо, если они изменят способ реализации create_update. Для простоты я предполагаю, что вы пытаетесь установить пользователя по умолчанию, а не молча заставить пользователя быть зарегистрированным пользователем.

Записать обработчик контекста:

from django.views.generic.create_update import get_model_and_form_class
def form_user_default(request):
    if request.method == 'GET':
        model, custom_form = get_model_and_form_class(Post,None)
        custom_form.author = request.user
        return {'form':custom_form}
    else: return {}

Что это будет делать, это переопределить объект формы, который create_update переходит к шаблону. То, что это технически делает, - это повторное создание формы после того, как это сделал по умолчанию.

Затем в вашем URL conf:

url(r'pattern_to_match', 'django.views.generic.create_update.create_object', kwargs={'context_processors':form_user_default})

Опять же, мне пришлось углубиться в исходный код, чтобы выяснить, как это сделать. Лучше всего попытаться написать собственное представление (но включить как можно больше пользовательских объектов Django). Нет никакого "простого дефолтного" способа сделать это, потому что в парадигмах django более тесно привязаны к слою модели, чем к представлениям, и только представления имеют знания объекта запроса.

Ответ 2

Возможно, вы захотите рассмотреть закрытие.

from django.forms import ModelForm
from django.views.generic.create_update import create_object, update_object

def make_foo_form(request):
    class FooForm(ModelForm):
        class Meta:
            model = Foo
            fields = ['foo', 'bar']

        def save(self, commit=True):
            f = super(FooForm, self).save(commit=False)
            if not f.pk: f.user = request.user
            if commit: f.save()
            return f

    return FooForm

def create_foo(request):
    FooForm = make_foo_form(request)
    return create_object(form_class=FooForm)

Здесь есть некоторая неэффективность, так как вам нужно создать объект ModelForm для каждого запроса, но это позволяет вам вводить функциональность в общий вид.

Вам нужно решить, стоит ли добавлять сложность для создания формы, чтобы упростить ее на стороне представления.

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

def update_foo(request, object_id):
    FooForm = make_foo_form(request)
    return update_object(form_class=FooForm, object_id=object_id)

Очевидно, вы можете использовать этот подход и для более сложных случаев.

Ответ 3

Если пользователь аутентифицирован, их пользовательский объект является объектом request.user.

Я не знаком с create_object... Я все еще новичок в django и только что начал с ним свой первый настоящий проект.

Обратите внимание, что вы должны проверить, чтобы пользователь вошел в систему, прежде чем использовать это. Это можно сделать с помощью request.user.is_authenticated().

Ответ 4

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

По этой причине я уже использую свои собственные общие представления на основе классов.

Ответ 5

Я бы предложил создать обертку для create_object, как это предлагает автор http://www.b-list.org/weblog/2006/nov/16/django-tips-get-most-out-generic-views/ в представлении вы получите доступ к информации о пользователе. После этого вам нужно будет использовать extra_context, чтобы передать пользователя шаблону. Наконец, в шаблоне вы можете добавить скрытое поле с информацией о пользователе. Я не пробовал, но об этом уже давно думаю. Надеюсь, это решение вам подходит! ;) приветствия!