Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 22, 2013 17:09:32

infoforfoi
Зарегистрирован: 2013-01-20
Сообщения: 33
Репутация: +  0  -
Профиль   Отправить e-mail  

несколько форм Django

Вопрос элементарный, но не смог победить.

2 таблицы UserProfile (Пользователь) и Estates (Товар пользователя)
views.py

    estates_obj = Estates.objects.filter(userprofile__user__username__exact=username)[0]
if request.method == 'POST':
form = EstatesForm(data=request.POST, files=request.FILES, instance=estates_obj)
if form.is_valid():
form.save()
return HttpResponseRedirect('')
else:
form = EstatesForm(instance=estates_obj)

Так все работает, если выводить только одну редактируемую форму пользователя.
Как сделать, чтобы выводило все редактируемые формы?
Спасибо

Офлайн

#2 Янв. 23, 2013 04:48:27

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

несколько форм Django

Для вопросов по Django есть отдельный форум



Офлайн

#3 Янв. 23, 2013 04:55:14

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

несколько форм Django

Точно так же как с одной формой

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ["username", "email"]
 
class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
 
#in views.py
def add_user(request):
    ...
    if request.method == "POST":
        uform = UserForm(data = request.POST)
        pform = UserProfileForm(data = request.POST)
        if uform.is_valid() and pform.is_valid():
            user = uform.save()
            profile = pform.save(commit = False)
            profile.user = user
            profile.save()
            ....
    ...

#in template
<form method="post">
    {{ uform.as_p }}
    {{ pform.as_p }}
    <input type="submit" ...>
</form> 



Офлайн

#4 Янв. 23, 2013 09:38:34

infoforfoi
Зарегистрирован: 2013-01-20
Сообщения: 33
Репутация: +  0  -
Профиль   Отправить e-mail  

несколько форм Django

Это мое первое сообщение извини, если не туда вписал, впредь буду внимательнее
Спасибо за ответ, но…

Может не совсем понятно объяснился.
Пользователь 1, у него много Товара, т.е. форма тоже одна, но для каждого Товара отдельная

estates_obj = Estates.objects.filter
(userprofile__user__username__exact=username) # тут убираем [0]
for n in estates_obj:
# где-то тут должен быть цикл, но это пока выше моего понимания
if request.method == 'POST':

подсказывают формсетом, но сколько не читал, пока не вникну как

Офлайн

#5 Янв. 23, 2013 09:48:06

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

несколько форм Django

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



Офлайн

#6 Янв. 23, 2013 13:39:48

infoforfoi
Зарегистрирован: 2013-01-20
Сообщения: 33
Репутация: +  0  -
Профиль   Отправить e-mail  

несколько форм Django

дошел до:

forms.py

class EstatesForm(ModelForm):
    class Meta:
      model = Estates
      fields = ('type_estate', 'cost', 'bargain', )
      
class BaseEstatesFormSet(BaseModelFormSet):
    def __init__(self, *args, **kwargs):
        super(BaseEstatesFormSet, self).__init__(*args, **kwargs)
        self.queryset = Estates.objects.all()
        
EstatesFormSet = modelformset_factory(Estates, form=EstatesForm, formset=BaseEstatesFormSet, extra=1)

views.py
    if request.method == 'POST':
        formset = EstatesFormSet(data=request.POST, files=request.FILES)
        if formset.is_valid():
            for n in formset.save(commit=False):
                formset.save()
            return HttpResponseRedirect('')
    else:
        formset = EstatesFormSet() 

templates.py
{{ formset }}

Выдает список форм с возможностью редактирования их, но пока все формы заполнены данными только одной записи

пытаюсь заполнить каждую форму Товара одного Пользователя разными записями из таблицы Товары
(т.е. на всякий, еще раз: Пользователь видит на странице, все свои Товары, в виде редактируемых форм)

        formset = EstatesFormSet(data=request.POST, files=request.FILES)
for form in formset:
if form.is_valid():
form.save()
return HttpResponseRedirect('')

        if formset.is_valid():
for n in formset.save():
n.userprofile__user__username__exact = request.username
n.save()

сложно строить логику, когда объекты не до конца изучены
может подскажите, один шаг до завершения этого проекта

в учебнике это выглядит, так:
>>> for form in formset:
.... print form.as_table()
как это реализовать не в shell, а в views?

Офлайн

#7 Янв. 23, 2013 14:56:56

buddha
От:
Зарегистрирован: 2012-03-02
Сообщения: 422
Репутация: +  15  -
Профиль   Отправить e-mail  

несколько форм Django

Я пока отвечал сайт лёг.

Всё верно. Используй formset.

Будет так в твоём случае:

from django.forms.models import  modelformset_factory
# ...                           остальные импорты
def show_edit_estates(request):
    model_formset = modelformset_factory(Estates) # тут еще интересные параметры exclude, fields, can_delete, can_order
    if request.POST:
        formset = model_formset(request.POST, request.FILES, queryset=Estates.objects.filter(userprofile__user__username__exact=username))
        if formset.is_valid():                          # если не указать queryset, по умолчанию будет Estates.objects.all()
            estates_objects = formset.save(commit=False) # если не нужно менять ничего в объекте просто formset.save()
            for obj in estates_objects: # если какое то поле хочешь поменять вручную
                obj.some_field = 'adqwqe' # точно так же, как и с одиночной формой
                obj.save
                return HttpResponseRedirect('')
    else:
        formset = model_formset(queryset=Estates.objects.filter(userprofile__user__username__exact=username))
        return render(request, 'template.html', dict(formset=formset))

В шаблоне template.html:
<form action="{% url edit_estates %}" method="POST">{% csrf_token %}
            {{ formset.management_form }} {# обязательно выводить этот аргумент!!! #}
            {% for form in formset %}
                <div class="well">
                    {{ form }} {# тут уже как с обычной формой работай #}
                    <br>
                </div>
            {% endfor %}
            <input type="submit" class="btn" value="SAVE">
        </form>

За подробным описанием работы и возможностей
https://docs.djangoproject.com/en/1.4/topics/forms/formsets/

https://docs.djangoproject.com/en/1.4/topics/forms/modelforms/#model-formsets

Отпишись, что получилось. Сам не так давно подобное делал.

Офлайн

#8 Янв. 24, 2013 07:20:19

infoforfoi
Зарегистрирован: 2013-01-20
Сообщения: 33
Репутация: +  0  -
Профиль   Отправить e-mail  

несколько форм Django

Не знаю как тебя благодарить. Решил делать проект на Джанго, все просто супер, но логика требует опыта. Кстати, читал ту же документацию на русском, на английском она более полная.

Вывод форм происходит именно так как и хотелось бы.
+ Сохраняет введенные данные в новую форму из extra=1
- Но формы с имеющимися данными пока не перезаписывает.

Еще вопрос, как связать с forms.py, BaseEstatesFormSet, чтобы была возможность редактирования?

model_formset = modelformset_factory(Estates, EstatesFormSet) # что-то типа такого должно быть?

Редактирую django-profiles

Отредактировано infoforfoi (Янв. 24, 2013 10:03:28)

Офлайн

#9 Янв. 24, 2013 10:03:17

infoforfoi
Зарегистрирован: 2013-01-20
Сообщения: 33
Репутация: +  0  -
Профиль   Отправить e-mail  

несколько форм Django

Вот оно решение:

    model_formset = modelformset_factory(Estates, form=EstatesForm) 
    if request.POST:
        formset = model_formset(request.POST, request.FILES, queryset=Estates.objects.filter(userprofile__user__username__exact=username)) 
        if formset.is_valid():
            estates_objects = formset.save(commit=False) 
            for obj in estates_objects:
                obj.save()
                return HttpResponseRedirect('')
    else:
        formset = model_formset(queryset=Estates.objects.filter(userprofile__user__username__exact=username))
        return render(request, template_name, dict(formset=formset)) 

Отредактировано infoforfoi (Янв. 24, 2013 11:52:22)

Офлайн

#10 Янв. 24, 2013 11:53:57

infoforfoi
Зарегистрирован: 2013-01-20
Сообщения: 33
Репутация: +  0  -
Профиль   Отправить e-mail  

несколько форм Django

А как в новой форме из из extra=1, задать в поле Пользователя - текущего?

так понимаю, задается где-то здесь:

            estates_objects = formset.save(commit=False)
            for obj in estates_objects:
                obj.userprofile = request.user.username # тут вроде как
                obj.save()
                return HttpResponseRedirect('')

есть такие параметры:
def profile_detail(request, username, public_profile_field=None, form_class=None, success_url=None,
                   template_name='profiles/profile_detail.html',
                   extra_context=None):

Отредактировано infoforfoi (Янв. 24, 2013 12:03:52)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version